コード例 #1
0
ファイル: spawn2.cpp プロジェクト: Derision/Server
bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 instance_id)
{
	char errbuf[MYSQL_ERRMSG_SIZE];
	char* query = 0;
	MYSQL_RES *result;
	MYSQL_ROW row;
	int len;

	//clear out old stuff..
	spawn_conditions.clear();

	//load spawn conditions
	SpawnCondition cond;
	len = MakeAnyLenString(&query, "SELECT id, onchange, value FROM spawn_conditions WHERE zone='%s'", zone_name);
	if (database.RunQuery(query, len, errbuf, &result)) {
		safe_delete_array(query);
		while((row = mysql_fetch_row(result))) {
			cond.condition_id = atoi(row[0]);
			cond.value = atoi(row[2]);
			cond.on_change = (SpawnCondition::OnChange) atoi(row[1]);
			spawn_conditions[cond.condition_id] = cond;

			_log(SPAWNS__CONDITIONS, "Loaded spawn condition %d with value %d and on_change %d", cond.condition_id, cond.value, cond.on_change);
		}
		mysql_free_result(result);
	} else {
		LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query, errbuf);
		safe_delete_array(query);
		return false;
	}

	//load values
	len = MakeAnyLenString(&query, "SELECT id, value FROM spawn_condition_values WHERE zone='%s' and instance_id=%u", zone_name, instance_id);
	if (database.RunQuery(query, len, errbuf, &result)) {
		safe_delete_array(query);
		while((row = mysql_fetch_row(result)))
		{
			std::map<uint16, SpawnCondition>::iterator iter = spawn_conditions.find(atoi(row[0]));
			if(iter != spawn_conditions.end())
			{
				iter->second.value = atoi(row[1]);
			}
		}
		mysql_free_result(result);
	}
	else
	{
		LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query, errbuf);
		safe_delete_array(query);
		spawn_conditions.clear();
		return false;
	}

	//load spawn events
	SpawnEvent event;
	len = MakeAnyLenString(&query,
		"SELECT id,cond_id,period,next_minute,next_hour,next_day,next_month,next_year,enabled,action,argument "
		"FROM spawn_events WHERE zone='%s'", zone_name);
	if (database.RunQuery(query, len, errbuf, &result)) {
		safe_delete_array(query);
		while((row = mysql_fetch_row(result))) {
			event.id = atoi(row[0]);
			event.condition_id = atoi(row[1]);
			event.period = atoi(row[2]);
			if(event.period == 0) {
				LogFile->write(EQEMuLog::Error, "Refusing to load spawn event #%d because it has a period of 0\n", event.id);
				continue;
			}

			event.next.minute = atoi(row[3]);
			event.next.hour = atoi(row[4]);
			event.next.day = atoi(row[5]);
			event.next.month = atoi(row[6]);
			event.next.year = atoi(row[7]);

			event.enabled = atoi(row[8])==0?false:true;
			event.action = (SpawnEvent::Action) atoi(row[9]);
			event.argument = atoi(row[10]);
			spawn_events.push_back(event);

			_log(SPAWNS__CONDITIONS, "Loaded %s spawn event %d on condition %d with period %d, action %d, argument %d",
				event.enabled?"enabled":"disabled", event.id, event.condition_id, event.period, event.action, event.argument);
		}
		mysql_free_result(result);
	} else {
		LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions events query '%s': %s", query, errbuf);
		safe_delete_array(query);
		return false;
	}

	//now we need to catch up on events that happened while we were away
	//and use them to alter just the condition variables.

	//each spawn2 will then use its correct condition value when
	//it decides what to do. This essentially forces a 'depop' action
	//on spawn points which are turned off, and a 'repop' action on
	//spawn points which get turned on. Im too lazy to figure out a
	//better solution, and I just dont care thats much.
	//get our current time
	TimeOfDay_Struct tod;
	zone->zone_time.getEQTimeOfDay(&tod);

	std::vector<SpawnEvent>::iterator cur,end;
	cur = spawn_events.begin();
	end = spawn_events.end();
	bool ran;
	for(; cur != end; cur++) {
		SpawnEvent &cevent = *cur;

		if(!cevent.enabled)
			continue;

		//watch for special case of all 0s, which means to reset next to now
		if(cevent.next.year == 0 && cevent.next.month == 0 && cevent.next.day == 0 && cevent.next.hour == 0 && cevent.next.minute == 0) {
			_log(SPAWNS__CONDITIONS, "Initial next trigger time set for spawn event %d", cevent.id);
			memcpy(&cevent.next, &tod, sizeof(cevent.next));
			//add one period
			EQTime::AddMinutes(cevent.period, &cevent.next);
			//save it in the db.
			UpdateDBEvent(cevent);
			continue;	//were done with this event.
		}

		ran = false;
		while(EQTime::IsTimeBefore(&tod, &cevent.next)) {
			_log(SPAWNS__CONDITIONS, "Catch up triggering on event %d", cevent.id);
			//this event has been triggered.
			//execute the event
			ExecEvent(cevent, false);
			//add the period of the event to the trigger time
			EQTime::AddMinutes(cevent.period, &cevent.next);
			ran = true;
		}
		//only write it out if the event actually ran
		if(ran) {
			//save the event in the DB
			UpdateDBEvent(cevent);
		}
	}

	//now our event timers are all up to date, find our closest event.
	FindNearestEvent();

	return(true);
}
コード例 #2
0
ファイル: pets.cpp プロジェクト: Corysia/Server
// Load the equipmentset from the DB. Might be worthwhile to load these into
// shared memory at some point due to the number of queries needed to load a
// nested set.
bool ZoneDatabase::GetBasePetItems(int32 equipmentset, uint32 *items) {
	if (equipmentset < 0 || items == nullptr)
		return false;

	// Equipment sets can be nested. We start with the top-most one and
	// add all items in it to the items array. Referenced equipmentsets
	// are loaded after that, up to a max depth of 5. (Arbitrary limit
	// so we don't go into an endless loop if the DB data is cyclic for
	// some reason.)
	// A slot will only get an item put in it if it is empty. That way
	// an equipmentset can overload a slot for the set(s) it includes.

	char errbuf[MYSQL_ERRMSG_SIZE];
	char *query = 0;
	uint32 querylen = 0;
	MYSQL_RES *result;
	MYSQL_ROW row;
	int depth = 0;
	int32 curset = equipmentset;
	int32 nextset = -1;
	uint32 slot;

	// outline:
	// get equipmentset from DB. (Mainly check if we exist and get the
	// nested ID)
	// query pets_equipmentset_entries with the set_id and loop over
	// all of the result rows. Check if we have something in the slot
	// already. If no, add the item id to the equipment array.

	while (curset >= 0 && depth < 5) {
		if (RunQuery(query,
			MakeAnyLenString(&query, "SELECT nested_set FROM pets_equipmentset WHERE set_id='%s'", curset),
			errbuf, &result))
		{
			safe_delete_array(query);
			if (mysql_num_rows(result) == 1) {
				row = mysql_fetch_row(result);
				nextset = atoi(row[0]);
				mysql_free_result(result);

				if (RunQuery(query,
					MakeAnyLenString(&query, "SELECT slot, item_id FROM pets_equipmentset_entries WHERE set_id='%s'", curset),
					errbuf, &result))
				{
					safe_delete_array(query);
					while ((row = mysql_fetch_row(result)))
					{
						slot = atoi(row[0]);
						if (slot >= MAX_WORN_INVENTORY)
							continue;
						if (items[slot] == 0)
							items[slot] = atoi(row[1]);
					}

					mysql_free_result(result);
				}
				else {
					LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems query '%s': %s", query, errbuf);
					safe_delete_array(query);
				}
				curset = nextset;
				depth++;
			}
			else
			{
				// invalid set reference, it doesn't exist
				LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems equipment set '%d' does not exist", curset);
				mysql_free_result(result);
				return false;
			}
		}
		else
		{
			LogFile->write(EQEMuLog::Error, "Error in GetBasePetItems query '%s': %s", query, errbuf);
			safe_delete_array(query);
			return false;
		}
	} // end while

	return true;
}
コード例 #3
0
void CWndPartyCtrl::OnDraw( C2DRender* p2DRender ) 
{
	if( NULL == g_pPlayer )
		return;

	CPoint pt( 3, 3 );

//	pt.y -= ( m_nFontHeight + 3 ) * m_wndScrollBar.GetScrollPos();

#if __VER < 11 // __CSC_VER11_4
	CWndMessenger* pWndMessenger = (CWndMessenger*)GetWndBase( APP_MESSENGER_ );
#endif //__CSC_VER11_4
	CWndWorld* pWndWorld = (CWndWorld*)g_WndMng.GetWndBase( APP_WORLD );
	
	int nMax = g_Party.m_nSizeofMember;
	// 눈에 보이는 갯수가 페이지라인수 보다 크면 보이는 갯수를 페이지라인수로 조정 
	if( nMax - m_wndScrollBar.GetScrollPos() > m_wndScrollBar.GetScrollPage() )
		nMax = m_wndScrollBar.GetScrollPage() + m_wndScrollBar.GetScrollPos();
	if( nMax < m_wndScrollBar.GetScrollPos() )
		nMax = 0;
	
	TEXTUREVERTEX2* pVertex = new TEXTUREVERTEX2[ 6 * 2 * nMax ];
	TEXTUREVERTEX2* pVertices = pVertex;
	
	for( int i = m_wndScrollBar.GetScrollPos(); i < nMax; i++ ) 
	{
		CMover* pObjMember = prj.GetUserByID( g_Party.m_aMember[i].m_uPlayerId );
		CString strMember;
#if __VER >= 11 // __SYS_PLAYER_DATA
		PlayerData* pPlayerData	= CPlayerDataCenter::GetInstance()->GetPlayerData( g_Party.m_aMember[i].m_uPlayerId );
		int nJob	= pPlayerData->data.nJob;
		int nSex	= pPlayerData->data.nSex;
#else	// __SYS_PLAYER_DATA
		int nJob	= g_Party.m_aMember[ i ].m_nJob;
		int nSex	= g_Party.m_aMember[ i ].m_nSex;
#endif	// __SYS_PLAYER_DATA
		
		// 상태에 따라 색 변경
		DWORD dwColor = 0xff000000;
		if( IsValidObj(pObjMember) )
		{
			if( pObjMember->GetHitPoint() == 0 ) 
				dwColor = 0xffff0000; // 죽은놈
			else 
				if( ((FLOAT)pObjMember->GetHitPoint()) / ((FLOAT)pObjMember->GetMaxHitPoint()) < 0.1f ) 
					dwColor = 0xffffff00; // HP 10% 이하인 놈
			strMember.Format( "%d %s", pObjMember->GetLevel(), pObjMember->GetName() );
		}
		else
		{
			dwColor = 0xff878787; // 디폴트는 주위에 없는 놈
			if( g_Party.m_aMember[ i ].m_bRemove ) 
				dwColor = 0xff000000; // 서버에 없는 놈
#if __VER >= 11 // __SYS_PLAYER_DATA
			strMember.Format( "?? %s", pPlayerData->szPlayer );
#else	// __SYS_PLAYER_DATA
			strMember.Format( "?? %s", g_Party.m_aMember[ i ].m_szName );
#endif	// __SYS_PLAYER_DATA
		}
		if( i == m_nCurSelect )
			dwColor = 0xff6060ff; 

		int x = 0, nWidth = m_rectClient.Width() - 10;// - 1;

		CRect rect( x, pt.y, x + nWidth, pt.y + m_nFontHeight );

		rect.SetRect( x + 20, pt.y + 18, x + nWidth - 10, pt.y + 30 ); 
		nWidth	= pObjMember ? pObjMember->GetHitPointPercent( rect.Width() ) : 0;
		CRect rectTemp = rect; 
		rectTemp.right = rectTemp.left + nWidth;
		if( rect.right < rectTemp.right )
			rectTemp.right = rect.right;

		m_pTheme->RenderGauge( p2DRender, &rect, 0xffffffff, m_pVBGauge, &m_texGauEmptyNormal );
		m_pTheme->RenderGauge( p2DRender, &rectTemp, 0x64ff0000, m_pVBGauge, &m_texGauFillNormal );

		rect.SetRect( x + 3, pt.y, x + 3 + 32, pt.y + 6 + 32 ); 

		p2DRender->TextOut( x + 20, pt.y + 3, strMember, dwColor ); 

		if( MAX_EXPERT <= nJob )
		{
#if __VER >= 10 // __LEGEND
			if( MAX_PROFESSIONAL <= nJob && nJob < MAX_MASTER )
				pWndWorld->m_texMsgIcon.MakeVertex( p2DRender, CPoint( 2, pt.y ),  ( 70 + nJob - 16 ) + ( 8 * nSex ), &pVertices, 0xffffffff );
			else if( MAX_MASTER <= nJob )
				pWndWorld->m_texMsgIcon.MakeVertex( p2DRender, CPoint( 2, pt.y ),  ( 70 + nJob - 24 ) + ( 8 * nSex ), &pVertices, 0xffffffff );
			else
#endif //__LEGEND
			pWndWorld->m_texMsgIcon.MakeVertex( p2DRender, CPoint( 2, pt.y ),  ( 70 + nJob - 6 ) + ( 8 * nSex ), &pVertices, 0xffffffff );
		}
		else
		{
			pWndWorld->m_texMsgIcon.MakeVertex( p2DRender, CPoint( 2, pt.y ),  12 + nJob + ( 6 * nSex ), &pVertices, 0xffffffff );
		}

		pt.y += m_nFontHeight + 3;
	}
	pWndWorld->m_texMsgIcon.Render( m_pApp->m_pd3dDevice, pVertex, ( (int) pVertices - (int) pVertex ) / sizeof( TEXTUREVERTEX2 ) );
	safe_delete_array( pVertex );
}
コード例 #4
0
ファイル: Titanium.cpp プロジェクト: Derision/Server
char *SerializeItem(const ItemInst *inst, int16 slot_id, uint32 *length, uint8 depth) {
	char *serialization = nullptr;
	char *instance = nullptr;
	const char *protection=(const char *)"\\\\\\\\\\";
	char *sub_items[10] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
	bool stackable=inst->IsStackable();
	uint32 merchant_slot=inst->GetMerchantSlot();
	int16 charges=inst->GetCharges();
	const Item_Struct *item=inst->GetItem();
	int i;
	uint32 sub_length;

	MakeAnyLenString(&instance,
		"%i|%i|%i|%i|%i|%i|%i|%i|%i|%i|%i|",
		stackable ? charges : 0,
		0,
		(merchant_slot==0) ? slot_id : merchant_slot,
		inst->GetPrice(),
		(merchant_slot==0) ? 1 : inst->GetMerchantCount(),
		0,
		//merchant_slot,	//instance ID, bullshit for now
		(merchant_slot==0) ? inst->GetSerialNumber() : merchant_slot,
		0,
		(stackable ? ((inst->GetItem()->ItemType == ItemTypePotion) ? 1 : 0) : charges),
		inst->IsInstNoDrop() ? 1 : 0,
		0
	);

	for(i=0;i<10;i++) {
		ItemInst *sub=inst->GetItem(i);
		if (sub) {
			sub_items[i]=SerializeItem(sub,0,&sub_length,depth+1);
		}
	}


	*length=MakeAnyLenString(&serialization,
		"%.*s%s"	// For leading quotes (and protection) if a subitem;
		"%s"		// Instance data
		"%.*s\""	// Quotes (and protection, if needed) around static data
		"%i"		// item->ItemClass so we can do |%s instead of %s|
#define I(field) "|%i"
#define C(field) "|%s"
#define S(field) "|%s"
#define F(field) "|%f"
#include "Titanium_itemfields.h"
		"%.*s\""	// Quotes (and protection, if needed) around static data
		"|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s"	// Sub items
		"%.*s%s"	// For trailing quotes (and protection) if a subitem;
		,depth ? depth-1 : 0,protection,(depth) ? "\"" : ""
		,instance
		,depth,protection
		,item->ItemClass
#define I(field) ,item->field
#define C(field) ,field
#define S(field) ,item->field
#define F(field) ,item->field
#include "Titanium_itemfields.h"
		,depth,protection
		,sub_items[0] ? sub_items[0] : ""
		,sub_items[1] ? sub_items[1] : ""
		,sub_items[2] ? sub_items[2] : ""
		,sub_items[3] ? sub_items[3] : ""
		,sub_items[4] ? sub_items[4] : ""
		,sub_items[5] ? sub_items[5] : ""
		,sub_items[6] ? sub_items[6] : ""
		,sub_items[7] ? sub_items[7] : ""
		,sub_items[8] ? sub_items[8] : ""
		,sub_items[9] ? sub_items[9] : ""
		,(depth) ? depth-1 : 0,protection,(depth) ? "\"" : ""
	);

	for(i=0;i<10;i++) {
		if (sub_items[i])
			safe_delete_array(sub_items[i]);
	}

	safe_delete_array(instance);
	return serialization;
}
コード例 #5
0
ファイル: worldserver.cpp プロジェクト: N0ctrnl/VAServer
void WorldServer::ProcessMessage(uint16 opcode, EQ::Net::Packet &p)
{
	ServerPacket tpack(opcode, p);
	ServerPacket *pack = &tpack;

	Log(Logs::Detail, Logs::UCS_Server, "Received Opcode: %4X", opcode);

	switch (opcode)
	{
	case 0: {
		break;
	}
	case ServerOP_KeepAlive:
	{
		break;
	}
	case ServerOP_UCSMessage:
	{
		char *Buffer = (char *)pack->pBuffer;

		auto From = new char[strlen(Buffer) + 1];

		VARSTRUCT_DECODE_STRING(From, Buffer);

		std::string Message = Buffer;

		Log(Logs::Detail, Logs::UCS_Server, "Player: %s, Sent Message: %s", From, Message.c_str());

		Client *c = g_Clientlist->FindCharacter(From);

		safe_delete_array(From);

		if (Message.length() < 2)
			break;

		if (!c)
		{
			Log(Logs::Detail, Logs::UCS_Server, "Client not found.");
			break;
		}

		if (Message[0] == ';')
		{
			std::string new_message;
			switch (c->GetClientVersion()) {
			case EQEmu::versions::ClientVersion::Titanium:
				Client45ToServerSayLink(new_message, Message.substr(1, std::string::npos));
				break;
			case EQEmu::versions::ClientVersion::SoF:
			case EQEmu::versions::ClientVersion::SoD:
			case EQEmu::versions::ClientVersion::UF:
				Client50ToServerSayLink(new_message, Message.substr(1, std::string::npos));
				break;
			case EQEmu::versions::ClientVersion::RoF:
				Client55ToServerSayLink(new_message, Message.substr(1, std::string::npos));
				break;
			case EQEmu::versions::ClientVersion::RoF2:
			default:
				new_message = Message.substr(1, std::string::npos);
				break;
			}

			c->SendChannelMessageByNumber(new_message);
		}
		else if (Message[0] == '[')
		{
			g_Clientlist->ProcessOPMailCommand(c, Message.substr(1, std::string::npos));
		}

		break;
	}

	case ServerOP_UCSMailMessage:
	{
		ServerMailMessageHeader_Struct *mail = (ServerMailMessageHeader_Struct*)pack->pBuffer;
		database.SendMail(std::string("SOE.EQ.") + Config->ShortName + std::string(".") + std::string(mail->to),
			std::string(mail->from),
			mail->subject,
			mail->message,
			std::string());
		break;
	}
	}
}
コード例 #6
0
ファイル: tcp_connection.cpp プロジェクト: aaronze/Server
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;
}
コード例 #7
0
ファイル: emu_tcp_connection.cpp プロジェクト: jcon321/Server
/*
C28182	Dereferencing a copy of a null pointer	Dereferencing NULL pointer.
'recvbuf' contains the same NULL value as 'size' did.
common	emu_tcp_connection.cpp										537
'size' is equal to 7												531
Enter this branch, (assume 'recvbuf!=0')							534
Enter this loop, (assume '((recvbuf_used-base))>=size')				536
Skip this branch, (assume 'size>=524288' is false)					540
Skip this branch, (assume '((recvbuf_used-base))>=size' is false)	549
Continue this loop, (assume '((recvbuf_used-base))>=size')			536
'size' is dereferenced, but may still be NULL						537
*/
bool EmuTCPConnection::ProcessReceivedDataAsPackets(char* errbuf) {
	if (errbuf)
		errbuf[0] = 0;
	int32 base = 0;
	int32 size = 7;
	uchar* buffer;
	ServerPacket* pack = 0;
	while ((recvbuf_used - base) >= size) {
		EmuTCPNetPacket_Struct* tnps = (EmuTCPNetPacket_Struct*) &recvbuf[base];
		buffer = tnps->buffer;
		size = tnps->size;
		if (size >= MaxTCPReceiveBuffferSize) {
#if TCPN_DEBUG_Memory >= 1
			std::cout << "TCPConnection[" << GetID() << "]::ProcessReceivedDataAsPackets(): size[" << size << "] >= MaxTCPReceiveBuffferSize" << std::endl;
			DumpPacket(&recvbuf[base], 16);
#endif
			if (errbuf)
				snprintf(errbuf, TCPConnection_ErrorBufferSize, "EmuTCPConnection::ProcessReceivedDataAsPackets(): size >= MaxTCPReceiveBuffferSize");
			return false;
		}
		if ((recvbuf_used - base) >= size) {
			// ok, we got enough data to make this packet!
			pack = new ServerPacket;
			pack->size = size - sizeof(EmuTCPNetPacket_Struct);
			// read headers
			pack->opcode = tnps->opcode;
			if (tnps->flags.compressed) {
				pack->compressed = true;
				pack->InflatedSize = *((int32*)buffer);
				pack->size -= 4;
				buffer += 4;
			}
			if (tnps->flags.destination) {
				pack->destination = *((int32*)buffer);
				pack->size -= 4;
				buffer += 4;
			}
			// end read headers
			if (pack->size > 0) {
				if (tnps->flags.compressed) {
					// Lets decompress the packet here
					pack->compressed = false;
					pack->pBuffer = new uchar[pack->InflatedSize];
					pack->size = InflatePacket(buffer, pack->size, pack->pBuffer, pack->InflatedSize);
				}
				else {
					pack->pBuffer = new uchar[pack->size];
					memcpy(pack->pBuffer, buffer, pack->size);
				}
			}
			if (pack->opcode == 0) {
				if (pack->size) {
					#if TCPN_DEBUG >= 2
						std::cout << "Received TCP Network layer packet" << std::endl;
					#endif
					ProcessNetworkLayerPacket(pack);
				}
				#if TCPN_DEBUG >= 5
					else {
						std::cout << "Received TCP keepalive packet. (opcode=0)" << std::endl;
					}
				#endif
				// keepalive, no need to process
				safe_delete(pack);
			}
			else {
				#if TCPN_LOG_PACKETS >= 1
					if (pack && pack->opcode != 0) {
						struct in_addr	in;
						in.s_addr = GetrIP();
						CoutTimestamp(true);
						std::cout << ": Logging incoming TCP packet. OPCode: 0x" << std::hex << std::setw(4) << std::setfill('0') << pack->opcode << std::dec << ", size: " << std::setw(5) << std::setfill(' ') << pack->size << " " << inet_ntoa(in) << ":" << GetrPort() << std::endl;
						#if TCPN_LOG_PACKETS == 2
							if (pack->size >= 32)
								DumpPacket(pack->pBuffer, 32);
							else
								DumpPacket(pack);
						#endif
						#if TCPN_LOG_PACKETS >= 3
							DumpPacket(pack);
						#endif
					}
				#endif
				if (RelayServer && Server && pack->destination) {
					EmuTCPConnection* con = Server->FindConnection(pack->destination);
					if (!con) {
						#if TCPN_DEBUG >= 1
							std::cout << "Error relaying packet: con = 0" << std::endl;
						#endif
						safe_delete(pack);
					}
					else
						con->OutQueuePush(pack);
				}
				else
					OutQueuePush(pack);
			}
			base += size;
			size = 7;
		}
	}
	if (base != 0) {
		if (base >= recvbuf_used) {
			safe_delete_array(recvbuf);
		} else {
			uchar* tmpbuf = new uchar[recvbuf_size - base];
			memcpy(tmpbuf, &recvbuf[base], recvbuf_used - base);
			safe_delete_array(recvbuf);
			recvbuf = tmpbuf;
			recvbuf_used -= base;
			recvbuf_size -= base;
		}
	}
	return true;
}
コード例 #8
0
ファイル: worlddb.cpp プロジェクト: Corysia/Server
bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc)
{
	char errbuf[MYSQL_ERRMSG_SIZE];
	char *query = 0;
	MYSQL_RES *result;
	MYSQL_ROW row = 0;
	int rows;

	if(!in_pp || !in_cc)
		return false;

	in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0;
	in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = 0;

	if(!RunQuery(query, MakeAnyLenString(&query, "SELECT x,y,z,heading,zone_id,bind_id FROM start_zones WHERE player_choice=%i AND player_class=%i "
			"AND player_deity=%i AND player_race=%i",
			in_cc->start_zone,
			in_cc->class_,
			in_cc->deity,
			in_cc->race), errbuf, &result))
	{
		LogFile->write(EQEMuLog::Error, "Start zone query failed: %s : %s\n", query, errbuf);
		safe_delete_array(query);
		return false;
	}

	LogFile->write(EQEMuLog::Status, "Start zone query: %s\n", query);
	safe_delete_array(query);

	if((rows = mysql_num_rows(result)) > 0)
		row = mysql_fetch_row(result);

	if(row)
	{
		LogFile->write(EQEMuLog::Status, "Found starting location in start_zones");
		in_pp->x = atof(row[0]);
		in_pp->y = atof(row[1]);
		in_pp->z = atof(row[2]);
		in_pp->heading = atof(row[3]);
		in_pp->zone_id = atoi(row[4]);
		in_pp->binds[0].zoneId = atoi(row[5]);
	}
	else
	{
		printf("No start_zones entry in database, using defaults\n");
		switch(in_cc->start_zone)
		{
			case 0:
			{
				in_pp->zone_id = 24;	// erudnext
				in_pp->binds[0].zoneId = 38;	// tox
				break;
			}
			case 1:
			{
				in_pp->zone_id =2;	// qeynos2
				in_pp->binds[0].zoneId = 2;	// qeynos2
				break;
			}
			case 2:
			{
				in_pp->zone_id =29;	// halas
				in_pp->binds[0].zoneId = 30;	// everfrost
				break;
			}
			case 3:
			{
				in_pp->zone_id =19;	// rivervale
				in_pp->binds[0].zoneId = 20;	// kithicor
				break;
			}
			case 4:
			{
				in_pp->zone_id =9;	// freportw
				in_pp->binds[0].zoneId = 9;	// freportw
				break;
			}
			case 5:
			{
				in_pp->zone_id =40;	// neriaka
				in_pp->binds[0].zoneId = 25;	// nektulos
				break;
			}
			case 6:
			{
				in_pp->zone_id =52;	// gukta
				in_pp->binds[0].zoneId = 46;	// innothule
				break;
			}
			case 7:
			{
				in_pp->zone_id =49;	// oggok
				in_pp->binds[0].zoneId = 47;	// feerrott
				break;
			}
			case 8:
			{
				in_pp->zone_id =60;	// kaladima
				in_pp->binds[0].zoneId = 68;	// butcher
				break;
			}
			case 9:
			{
				in_pp->zone_id =54;	// gfaydark
				in_pp->binds[0].zoneId = 54;	// gfaydark
				break;
			}
			case 10:
			{
				in_pp->zone_id =61;	// felwithea
				in_pp->binds[0].zoneId = 54;	// gfaydark
				break;
			}
			case 11:
			{
				in_pp->zone_id =55;	// akanon
				in_pp->binds[0].zoneId = 56;	// steamfont
				break;
			}
			case 12:
			{
				in_pp->zone_id =82;	// cabwest
				in_pp->binds[0].zoneId = 78;	// fieldofbone
				break;
			}
			case 13:
			{
				in_pp->zone_id =155;	// sharvahl
				in_pp->binds[0].zoneId = 155;	// sharvahl
				break;
			}
		}
	}

	if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0)
		database.GetSafePoints(in_pp->zone_id, 0, &in_pp->x, &in_pp->y, &in_pp->z);

	if(in_pp->binds[0].x == 0 && in_pp->binds[0].y == 0 && in_pp->binds[0].z == 0)
		database.GetSafePoints(in_pp->binds[0].zoneId, 0, &in_pp->binds[0].x, &in_pp->binds[0].y, &in_pp->binds[0].z);
	if(result)
		mysql_free_result(result);
	return true;
}
コード例 #9
0
ファイル: worlddb.cpp プロジェクト: Corysia/Server
// solar: the current stuff is at the bottom of this function
void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* cs) {
	char errbuf[MYSQL_ERRMSG_SIZE];
	char* query = 0;
	MYSQL_RES *result;
	MYSQL_ROW row;
	Inventory *inv;

	for (int i=0; i<10; i++) {
		strcpy(cs->name[i], "<none>");
		cs->zone[i] = 0;
		cs->level[i] = 0;
			cs->tutorial[i] = 0;
		cs->gohome[i] = 0;
	}

	int char_num = 0;
	unsigned long* lengths;

	// Populate character info
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT name,profile,zonename,class,level FROM character_ WHERE account_id=%i order by name limit 10", account_id), errbuf, &result)) {
		safe_delete_array(query);
		while ((row = mysql_fetch_row(result))) {
			lengths = mysql_fetch_lengths(result);
			////////////
			////////////	This is the current one, the other are for converting
			////////////
			if ((lengths[1] == sizeof(PlayerProfile_Struct))) {
				strcpy(cs->name[char_num], row[0]);
				PlayerProfile_Struct* pp = (PlayerProfile_Struct*)row[1];
				uint8 clas = atoi(row[3]);
				uint8 lvl = atoi(row[4]);

				// Character information
				if(lvl == 0)
					cs->level[char_num]		= pp->level;	//no level in DB, trust PP
				else
					cs->level[char_num]		= lvl;
				if(clas == 0)
					cs->class_[char_num]	= pp->class_;	//no class in DB, trust PP
				else
					cs->class_[char_num]	= clas;
				cs->race[char_num]			= pp->race;
				cs->gender[char_num]		= pp->gender;
				cs->deity[char_num]			= pp->deity;
				cs->zone[char_num]			= GetZoneID(row[2]);
				cs->face[char_num]			= pp->face;
				cs->haircolor[char_num]		= pp->haircolor;
				cs->beardcolor[char_num]	= pp->beardcolor;
				cs->eyecolor2[char_num]		= pp->eyecolor2;
				cs->eyecolor1[char_num]		= pp->eyecolor1;
				cs->hairstyle[char_num]		= pp->hairstyle;
				cs->beard[char_num]			= pp->beard;
				cs->drakkin_heritage[char_num]	= pp->drakkin_heritage;
				cs->drakkin_tattoo[char_num]	= pp->drakkin_tattoo;
				cs->drakkin_details[char_num]	= pp->drakkin_details;

				if(RuleB(World, EnableTutorialButton) && (lvl <= RuleI(World, MaxLevelForTutorial)))
					cs->tutorial[char_num] = 1;

				if(RuleB(World, EnableReturnHomeButton)) {
					int now = time(nullptr);
					if((now - pp->lastlogin) >= RuleI(World, MinOfflineTimeToReturnHome))
						cs->gohome[char_num] = 1;
				}


				// This part creates home city entries for characters created before the home bind point was tracked.
				// Do it here because the player profile is already loaded and it's as good a spot as any. This whole block should
				// probably be removed at some point, when most accounts are safely converted.
				if(pp->binds[4].zoneId == 0) {
					bool altered = false;
					MYSQL_RES *result2;
					MYSQL_ROW row2;
					char startzone[50] = {0};

					// check for start zone variable (I didn't even know any variables were still being used...)
					if(database.GetVariable("startzone", startzone, 50)) {
						uint32 zoneid = database.GetZoneID(startzone);
						if(zoneid) {
							pp->binds[4].zoneId = zoneid;
							GetSafePoints(zoneid, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z);
							altered = true;
						}
					}
					else {
						RunQuery(query,
							MakeAnyLenString(&query,
							"SELECT zone_id,bind_id,x,y,z FROM start_zones "
							"WHERE player_class=%i AND player_deity=%i AND player_race=%i",
							pp->class_,
							pp->deity,
							pp->race
							),
							errbuf,
							&result2
						);
						safe_delete_array(query);

						// if there is only one possible start city, set it
						if(mysql_num_rows(result2) == 1) {
							row2 = mysql_fetch_row(result2);
							if(atoi(row2[1]) != 0) {		// if a bind_id is specified, make them start there
								pp->binds[4].zoneId = (uint32)atoi(row2[1]);
								GetSafePoints(pp->binds[4].zoneId, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z);
							}
							else {	// otherwise, use the zone and coordinates given
								pp->binds[4].zoneId = (uint32)atoi(row2[0]);
								float x = atof(row2[2]);
								float y = atof(row2[3]);
								float z = atof(row2[4]);
								if(x == 0 && y == 0 && z == 0)
									GetSafePoints(pp->binds[4].zoneId, 0, &x, &y, &z);

								pp->binds[4].x = x;
								pp->binds[4].y = y;
								pp->binds[4].z = z;
							}
							altered = true;
						}

						mysql_free_result(result2);
					}

					// update the player profile
					if(altered) {
						uint32 char_id = GetCharacterID(cs->name[char_num]);
						RunQuery(query,MakeAnyLenString(&query,"SELECT extprofile FROM character_ WHERE id=%i",char_id), errbuf, &result2);
						safe_delete_array(query);
						if(result2) {
							row2 = mysql_fetch_row(result2);
							ExtendedProfile_Struct* ext = (ExtendedProfile_Struct*)row2[0];
							SetPlayerProfile(account_id,char_id,pp,inv,ext, 0, 0, 5);
						}
						mysql_free_result(result2);
					}
				}	// end of "set start zone" block


				// Character's equipped items
				// @merth: Haven't done bracer01/bracer02 yet.
				// Also: this needs a second look after items are a little more solid
				// NOTE: items don't have a color, players MAY have a tint, if the
				// use_tint part is set. otherwise use the regular color
				inv = new Inventory;
				if(GetInventory(account_id, cs->name[char_num], inv))
				{
					for (uint8 material = 0; material <= 8; material++)
					{
						uint32 color;
						ItemInst *item = inv->GetItem(Inventory::CalcSlotFromMaterial(material));
						if(item == 0)
							continue;

						cs->equip[char_num][material] = item->GetItem()->Material;

						if(pp->item_tint[material].rgb.use_tint)	// they have a tint (LoY dye)
							color = pp->item_tint[material].color;
						else	// no tint, use regular item color
							color = item->GetItem()->Color;

						cs->cs_colors[char_num][material].color = color;

						// the weapons are kept elsewhere
						if ((material==MaterialPrimary) || (material==MaterialSecondary))
						{
							if(strlen(item->GetItem()->IDFile) > 2) {
								uint32 idfile=atoi(&item->GetItem()->IDFile[2]);
								if (material==MaterialPrimary)
									cs->primary[char_num]=idfile;
								else
									cs->secondary[char_num]=idfile;
							}
						}
					}
				}
				else
				{
					printf("Error loading inventory for %s\n", cs->name[char_num]);
				}
				safe_delete(inv);
				if (++char_num > 10)
					break;
			}
			else
			{
				std::cout << "Got a bogus character (" << row[0] << ") Ignoring!!!" << std::endl;
				std::cout << "PP length ="<<lengths[1]<<" but PP should be "<<sizeof(PlayerProfile_Struct) << std::endl;
				//DeleteCharacter(row[0]);
			}
		}
		mysql_free_result(result);
	}
	else
	{
		std::cerr << "Error in GetCharSelectInfo query '" << query << "' " << errbuf << std::endl;
		safe_delete_array(query);
		return;
	}

	return;
}
コード例 #10
0
ファイル: database.cpp プロジェクト: Corysia/Server
bool Database::SendMail(std::string Recipient, std::string From, std::string Subject, std::string Body, std::string RecipientsString) {

	int CharacterID;

	std::string CharacterName;

	//printf("Database::SendMail(%s, %s, %s)\n", Recipient.c_str(), From.c_str(), Subject.c_str());

	std::string::size_type LastPeriod = Recipient.find_last_of(".");

	if(LastPeriod == std::string::npos)
		CharacterName = Recipient;
	else
		CharacterName = Recipient.substr(LastPeriod+1);

	CharacterName[0] = toupper(CharacterName[0]);

	for(unsigned int i = 1; i < CharacterName.length(); i++)
		CharacterName[i] = tolower(CharacterName[i]);

	CharacterID = FindCharacter(CharacterName.c_str());

	_log(UCS__TRACE, "SendMail: CharacterID for recipient %s is %i", CharacterName.c_str(), CharacterID);

	if(CharacterID <= 0) return false;

	char errbuf[MYSQL_ERRMSG_SIZE];
	char* query = 0;

	char *EscSubject = new char[Subject.length() * 2 + 1];
	char *EscBody = new char[Body.length() * 2 + 1];

	DoEscapeString(EscSubject, Subject.c_str(), Subject.length());
	DoEscapeString(EscBody, Body.c_str(), Body.length());

	const char *MailQuery="INSERT INTO `mail` (`charid`, `timestamp`, `from`, `subject`, `body`, `to`, `status`) "
				"VALUES ('%i', %i, '%s', '%s', '%s', '%s', %i)";

	uint32 LastMsgID;

	int Now = time(nullptr); // time returns a 64 bit int on Windows at least, which vsnprintf doesn't like.

	if(!RunQuery(query, MakeAnyLenString(&query, MailQuery, CharacterID, Now, From.c_str(), EscSubject, EscBody,
						RecipientsString.c_str(), 1), errbuf, 0, 0, &LastMsgID)) {

		_log(UCS__ERROR, "SendMail: Query %s failed with error %s", query, errbuf);

		safe_delete_array(EscSubject);
		safe_delete_array(EscBody);
		safe_delete_array(query);

		return false;
	}

	_log(UCS__TRACE, "MessageID %i generated, from %s, to %s", LastMsgID, From.c_str(), Recipient.c_str());

	safe_delete_array(EscSubject);
	safe_delete_array(EscBody);
	safe_delete_array(query);

	Client *c = CL->IsCharacterOnline(CharacterName);

	if(c) {
		std::string FQN = GetMailPrefix() + From;

		c->SendNotification(c->GetMailBoxNumber(CharacterName), Subject, FQN, LastMsgID);
	}

	MailMessagesSent++;

	return true;
}
コード例 #11
0
ファイル: Fragment.cpp プロジェクト: cavedude00/eqmacemu
			Fragment::~Fragment()
			{
				safe_delete_array(data);
			}
コード例 #12
0
ファイル: database.cpp プロジェクト: Corysia/Server
void Database::SendHeaders(Client *c) {

	int UnknownField2 = 25015275;
	int UnknownField3 = 1;

	int CharacterID = FindCharacter(c->MailBoxName().c_str());
	_log(UCS__TRACE, "Sendheaders for %s, CharID is %i", c->MailBoxName().c_str(), CharacterID);
	if(CharacterID <= 0)
		return;


	char errbuf[MYSQL_ERRMSG_SIZE];
	char* query = 0;
	MYSQL_RES *result;
	MYSQL_ROW row;

	if (!RunQuery(query,MakeAnyLenString(&query, "select `msgid`,`timestamp`,`from`,`subject`, `status` from `mail` "
							"where `charid`=%i", CharacterID),errbuf,&result)){

		safe_delete_array(query);

		return ;
	}

	safe_delete_array(query);

	char Buf[100];

	uint32 NumRows = mysql_num_rows(result);

	int HeaderCountPacketLength = 0;

	sprintf(Buf, "%i", c->GetMailBoxNumber());
	HeaderCountPacketLength += (strlen(Buf) + 1);

	sprintf(Buf, "%i", UnknownField2);
	HeaderCountPacketLength += (strlen(Buf) + 1);

	sprintf(Buf, "%i", UnknownField3);
	HeaderCountPacketLength += (strlen(Buf) + 1);

	sprintf(Buf, "%i", NumRows);
	HeaderCountPacketLength += (strlen(Buf) + 1);

	EQApplicationPacket *outapp = new EQApplicationPacket(OP_MailHeaderCount, HeaderCountPacketLength);

	char *PacketBuffer = (char *)outapp->pBuffer;

	VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, c->GetMailBoxNumber());
	VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, UnknownField2);
	VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, UnknownField3);
	VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, NumRows);

	_pkt(UCS__PACKETS, outapp);

	c->QueuePacket(outapp);

	safe_delete(outapp);

	int RowNum = 0;

	while((row = mysql_fetch_row(result))) {


		int HeaderPacketLength = 0;

		sprintf(Buf, "%i", c->GetMailBoxNumber());
		HeaderPacketLength = HeaderPacketLength + strlen(Buf) + 1;
		sprintf(Buf, "%i", UnknownField2);
		HeaderPacketLength = HeaderPacketLength + strlen(Buf) + 1;
		sprintf(Buf, "%i", RowNum);
		HeaderPacketLength = HeaderPacketLength + strlen(Buf) + 1;

		HeaderPacketLength = HeaderPacketLength + strlen(row[0]) + 1;
		HeaderPacketLength = HeaderPacketLength + strlen(row[1]) + 1;
		HeaderPacketLength = HeaderPacketLength + strlen(row[4]) + 1;
		HeaderPacketLength = HeaderPacketLength + GetMailPrefix().length() + strlen(row[2]) + 1;
		HeaderPacketLength = HeaderPacketLength + strlen(row[3]) + 1;

		outapp = new EQApplicationPacket(OP_MailHeader, HeaderPacketLength);

		PacketBuffer = (char *)outapp->pBuffer;

		VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, c->GetMailBoxNumber());
		VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, UnknownField2);
		VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, RowNum);
		VARSTRUCT_ENCODE_STRING(PacketBuffer, row[0]);
		VARSTRUCT_ENCODE_STRING(PacketBuffer, row[1]);
		VARSTRUCT_ENCODE_STRING(PacketBuffer, row[4]);
		VARSTRUCT_ENCODE_STRING(PacketBuffer, GetMailPrefix().c_str()); PacketBuffer--;
		VARSTRUCT_ENCODE_STRING(PacketBuffer, row[2]);
		VARSTRUCT_ENCODE_STRING(PacketBuffer, row[3]);

		_pkt(UCS__PACKETS, outapp);

		c->QueuePacket(outapp);

		safe_delete(outapp);

		RowNum++;
	}

	mysql_free_result(result);

}
コード例 #13
0
bool TCPConnection::ConnectIP(uint32 in_ip, uint16 in_port, char* errbuf)
{
	if (errbuf)
	{
		errbuf[0] = 0;
	}
	if (ConnectionType != Outgoing)
	{
		// If this code runs, we got serious problems
		// Crash and burn.
		return false;
	}
	MState.lock();
	if (ConnectReady())
	{
		pState = TCPS_Connecting;
	}
	else
	{
		MState.unlock();
		SetAsyncConnect(false);
		return false;
	}
	MState.unlock();
	if (!pRunLoop)
	{
		pRunLoop = true;
#ifdef _WINDOWS
		_beginthread(TCPConnectionLoop, 0, this);
#else
		pthread_t thread;
		pthread_create(&thread, nullptr, TCPConnectionLoop, this);
#endif
	}

	connection_socket = INVALID_SOCKET;
	struct sockaddr_in	server_sin;

	if ((connection_socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET || connection_socket == 0)
	{
#ifdef _WINDOWS
		if (errbuf)
		{
			snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::Connect(): Allocating socket failed. Error: %i", WSAGetLastError());
#else
		if (errbuf)
		{
			snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::Connect(): Allocating socket failed. Error: %s", strerror(errno));
#endif
		}
		SetState(TCPS_Ready);
		SetAsyncConnect(false);
		return false;
	}
	server_sin.sin_family = AF_INET;
	server_sin.sin_addr.s_addr = in_ip;
	server_sin.sin_port = htons(in_port);

	// Establish a connection to the server socket.
#ifdef _WINDOWS
	if (connect(connection_socket, (PSOCKADDR) &server_sin, sizeof (server_sin)) == SOCKET_ERROR)
	{
		if (errbuf)
		{
			snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::Connect(): connect() failed. Error: %i", WSAGetLastError());
		}
		closesocket(connection_socket);
		connection_socket = 0;
		SetState(TCPS_Ready);
		SetAsyncConnect(false);
		return false;
	}
#else
	if (connect(connection_socket, (struct sockaddr *) &server_sin, sizeof (server_sin)) == SOCKET_ERROR)
	{
		if (errbuf)
		{
			snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::Connect(): connect() failed. Error: %s", strerror(errno));
		}
		close(connection_socket);
		connection_socket = 0;
		SetState(TCPS_Ready);
		SetAsyncConnect(false);
		return false;
	}
#endif
	int bufsize = 64 * 1024; // 64kbyte receive buffer, up from default of 8k
	setsockopt(connection_socket, SOL_SOCKET, SO_RCVBUF, (char*) &bufsize, sizeof(bufsize));
#ifdef _WINDOWS
	unsigned long nonblocking = 1;
	ioctlsocket(connection_socket, FIONBIO, &nonblocking);
#else
	fcntl(connection_socket, F_SETFL, O_NONBLOCK);
#endif

	SetEcho(false);
	ClearBuffers();
	rIP = in_ip;
	rPort = in_port;
	SetState(TCPS_Connected);
	SetAsyncConnect(false);
	return true;
}
void TCPConnection::ClearBuffers()
{
	LockMutex lock1(&MSendQueue);
	LockMutex lock3(&MRunLoop);
	LockMutex lock4(&MState);
	safe_delete_array(recvbuf);
	safe_delete_array(sendbuf);

	char* line = 0;
	while ((line = LineOutQueue.pop()))
	{
		safe_delete_array(line);
	}
}
コード例 #14
0
ファイル: perlpacket.cpp プロジェクト: Xackery/provztz
PerlPacket::~PerlPacket() {
	if(packet != NULL)
		safe_delete_array(packet);
}
コード例 #15
0
ファイル: tcp_connection.cpp プロジェクト: aaronze/Server
bool TCPConnection::RecvData(char* errbuf) {
	if (errbuf)
		errbuf[0] = 0;
	if (!Connected()) {
		return false;
	}

	int	status = 0;
	if (recvbuf == 0) {
		recvbuf = new uchar[5120];
		recvbuf_size = 5120;
		recvbuf_used = 0;
		recvbuf_echo = 0;
	}
	else if ((recvbuf_size - recvbuf_used) < 2048) {
		uchar* tmpbuf = new uchar[recvbuf_size + 5120];
		memcpy(tmpbuf, recvbuf, recvbuf_used);
		recvbuf_size += 5120;
		safe_delete_array(recvbuf);
		recvbuf = tmpbuf;
		if (recvbuf_size >= MaxTCPReceiveBuffferSize) {
			if (errbuf)
				snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::RecvData(): recvbuf_size >= MaxTCPReceiveBuffferSize");
			return false;
		}
	}

	status = recv(connection_socket, (char *) &recvbuf[recvbuf_used], (recvbuf_size - recvbuf_used), 0);

	if (status >= 1) {
#if TCPN_LOG_RAW_DATA_IN >= 1
		struct in_addr	in;
		in.s_addr = GetrIP();
		CoutTimestamp(true);
		std::cout << ": Read " << status << " bytes from network. (recvbuf_used = " << recvbuf_used << ") " << inet_ntoa(in) << ":" << GetrPort();
		std::cout << std::endl;
	#if TCPN_LOG_RAW_DATA_IN == 2
		int32 tmp = status;
		if (tmp > 32)
			tmp = 32;
		DumpPacket(&recvbuf[recvbuf_used], status);
	#elif TCPN_LOG_RAW_DATA_IN >= 3
		DumpPacket(&recvbuf[recvbuf_used], status);
	#endif
#endif
		recvbuf_used += status;
		if (!ProcessReceivedData(errbuf))
			return false;
	}
	else if (status == SOCKET_ERROR) {
#ifdef _WINDOWS
		if (!(WSAGetLastError() == WSAEWOULDBLOCK)) {
			if (errbuf)
				snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::RecvData(): Error: %i", WSAGetLastError());
			return false;
		}
#else
		if (!(errno == EWOULDBLOCK)) {
			if (errbuf)
				snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::RecvData(): Error: %s", strerror(errno));
			return false;
		}
#endif
	} else if (status == 0) {
		snprintf(errbuf, TCPConnection_ErrorBufferSize, "TCPConnection::RecvData(): Connection closed");
		return false;
	}

	return true;
}
コード例 #16
0
ファイル: worlddb.cpp プロジェクト: Corysia/Server
bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc)
{

	// SoF doesn't send the player_choice field in character creation, it now sends the real zoneID instead.
	//
	// For SoF, search for an entry in start_zones with a matching zone_id, class, race and deity.
	//
	// For now, if no row matching row is found, send them to Crescent Reach, as that is probably the most likely
	// reason for no match being found.
	//
	char errbuf[MYSQL_ERRMSG_SIZE];
	char *query = 0;
	MYSQL_RES *result;
	MYSQL_ROW row = 0;
	int rows;

	if(!in_pp || !in_cc)
		return false;

	in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0;
	in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = 0;

	if(!RunQuery(query, MakeAnyLenString(&query, "SELECT x,y,z,heading,bind_id FROM start_zones WHERE zone_id=%i AND player_class=%i "
			"AND player_deity=%i AND player_race=%i",
			in_cc->start_zone,
			in_cc->class_,
			in_cc->deity,
			in_cc->race), errbuf, &result))
	{
		LogFile->write(EQEMuLog::Status, "SoF Start zone query failed: %s : %s\n", query, errbuf);
		safe_delete_array(query);
		return false;
	}

	LogFile->write(EQEMuLog::Status, "SoF Start zone query: %s\n", query);
	safe_delete_array(query);

	if((rows = mysql_num_rows(result)) > 0)
		row = mysql_fetch_row(result);

	if(row)
	{
		LogFile->write(EQEMuLog::Status, "Found starting location in start_zones");
		in_pp->x = atof(row[0]);
		in_pp->y = atof(row[1]);
		in_pp->z = atof(row[2]);
		in_pp->heading = atof(row[3]);
		in_pp->zone_id = in_cc->start_zone;
		in_pp->binds[0].zoneId = atoi(row[4]);
	}
	else
	{
		printf("No start_zones entry in database, using defaults\n");

		if(in_cc->start_zone == RuleI(World, TutorialZoneID))
			in_pp->zone_id = in_cc->start_zone;
		else {
			in_pp->x = in_pp->binds[0].x = -51;
			in_pp->y = in_pp->binds[0].y = -20;
			in_pp->z = in_pp->binds[0].z = 0.79;
			in_pp->zone_id = in_pp->binds[0].zoneId = 394; // Crescent Reach.
		}

	}

	if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0)
		database.GetSafePoints(in_pp->zone_id, 0, &in_pp->x, &in_pp->y, &in_pp->z);

	if(in_pp->binds[0].x == 0 && in_pp->binds[0].y == 0 && in_pp->binds[0].z == 0)
		database.GetSafePoints(in_pp->binds[0].zoneId, 0, &in_pp->binds[0].x, &in_pp->binds[0].y, &in_pp->binds[0].z);
	if(result)
		mysql_free_result(result);
	return true;
}
コード例 #17
0
ファイル: tcp_connection.cpp プロジェクト: aaronze/Server
bool TCPConnection::ProcessReceivedData(char* errbuf) {
	if (errbuf)
		errbuf[0] = 0;
	if (!recvbuf)
		return true;
#if TCPN_DEBUG_Console >= 4
	if (recvbuf_used) {
		std::cout << "Starting Processing: recvbuf=" << recvbuf_used << std::endl;
		DumpPacket(recvbuf, recvbuf_used);
	}
#endif
	for (int i=0; i < recvbuf_used; i++) {
		if (GetEcho() && i >= recvbuf_echo) {
			Send(&recvbuf[i], 1);
			recvbuf_echo = i + 1;
		}
		switch(recvbuf[i]) {
		case 0: { // 0 is the code for clear buffer
				if (i==0) {
					recvbuf_used--;
					recvbuf_echo--;
					memmove(recvbuf, &recvbuf[1], recvbuf_used);
					i = -1;
				} else {
					if (i == recvbuf_used) {
						safe_delete_array(recvbuf);
						i = -1;
					}
					else {
						uchar* tmpdel = recvbuf;
						recvbuf = new uchar[recvbuf_size];
						memcpy(recvbuf, &tmpdel[i+1], recvbuf_used-i);
						recvbuf_used -= i + 1;
						recvbuf_echo -= i + 1;
						safe_delete_array(tmpdel);
						i = -1;
					}
				}
#if TCPN_DEBUG_Console >= 5
				std::cout << "Removed 0x00" << std::endl;
				if (recvbuf_used) {
					std::cout << "recvbuf left: " << recvbuf_used << std::endl;
					DumpPacket(recvbuf, recvbuf_used);
				}
				else
					std::cout << "recbuf left: None" << std::endl;
#endif
				m_previousLineEnd = false;
				break;
			}
			case 10:
			case 13: // newline marker
			{
				char *line = nullptr;
				if (i==0) { // empty line
					if(!m_previousLineEnd) {
						//char right before this was NOT a CR, report the empty line.
						line = new char[1];
						line[0] = '\0';
						m_previousLineEnd = true;
					} else {
						m_previousLineEnd = false;
					}
					recvbuf_used--;
					recvbuf_echo--;
					memcpy(recvbuf, &recvbuf[1], recvbuf_used);
					i = -1;
				} else {
					line = new char[i+1];
					memset(line, 0, i+1);
					memcpy(line, recvbuf, i);
#if TCPN_DEBUG_Console >= 3
					std::cout << "Line Out: " << std::endl;
					DumpPacket((uchar*) line, i);
#endif
					//line[i] = 0;
					uchar* tmpdel = recvbuf;
					recvbuf = new uchar[recvbuf_size];
					recvbuf_used -= i+1;
					recvbuf_echo -= i+1;
					memcpy(recvbuf, &tmpdel[i+1], recvbuf_used);
#if TCPN_DEBUG_Console >= 5
					std::cout << "i+1=" << i+1 << std::endl;
					if (recvbuf_used) {
						std::cout << "recvbuf left: " << recvbuf_used << std::endl;
						DumpPacket(recvbuf, recvbuf_used);
					}
					else
						std::cout << "recbuf left: None" << std::endl;
#endif
					safe_delete_array(tmpdel);
					i = -1;
					m_previousLineEnd = true;
				}


				if(line != nullptr) {
					bool finish_proc = false;
					finish_proc = LineOutQueuePush(line);
					if(finish_proc)
						return(true);	//break early as requested by LineOutQueuePush
				}

				break;
			}
			case 8: // backspace
			{
				if (i==0) { // nothin to backspace
					recvbuf_used--;
					recvbuf_echo--;
					memmove(recvbuf, &recvbuf[1], recvbuf_used);
					i = -1;
				} else {
					uchar* tmpdel = recvbuf;
					recvbuf = new uchar[recvbuf_size];
					memcpy(recvbuf, tmpdel, i-1);
					memcpy(&recvbuf[i-1], &tmpdel[i+1], recvbuf_used-i);
					recvbuf_used -= 2;
					recvbuf_echo -= 2;
					safe_delete_array(tmpdel);
					i -= 2;
				}
				break;
				m_previousLineEnd = false;
			}
			default:
				m_previousLineEnd = false;
		}
	}
	if (recvbuf_used < 0)
		safe_delete_array(recvbuf);
	return true;
}
コード例 #18
0
ファイル: web_interface.cpp プロジェクト: bwilliams1/Server
bool WebInterfaceConnection::Process()
{
	if (!stream || !stream->Connected())
		return false;

	ServerPacket *pack = 0;

	while((pack = stream->PopPacket()))
	{
		if (!authenticated)
		{
			if (WorldConfig::get()->SharedKey.length() > 0)
			{
				if (pack->opcode == ServerOP_ZAAuth && pack->size == 16)
				{
					uint8 tmppass[16];

					MD5::Generate((const uchar*) WorldConfig::get()->SharedKey.c_str(), WorldConfig::get()->SharedKey.length(), tmppass);

					if (memcmp(pack->pBuffer, tmppass, 16) == 0)
						authenticated = true;
					else
					{
						struct in_addr in;
						in.s_addr = GetIP();
						_log(WEB_INTERFACE__ERROR, "WebInterface authorization failed.");
						ServerPacket* pack = new ServerPacket(ServerOP_ZAAuthFailed);
						SendPacket(pack);
						delete pack;
						Disconnect();
						return false;
					}
				}
				else
				{
					struct in_addr in;
					in.s_addr = GetIP();
					_log(WEB_INTERFACE__ERROR, "WebInterface authorization failed.");
					ServerPacket* pack = new ServerPacket(ServerOP_ZAAuthFailed);
					SendPacket(pack);
					delete pack;
					Disconnect();
					return false;
				}
			}
			else
			{
				_log(WEB_INTERFACE__ERROR, "**WARNING** You have not configured a world shared key in your config file. You should add a <key>STRING</key> element to your <world> element to prevent unauthorized zone access.");
				authenticated = true;
			}
			delete pack;
			continue;
		}
		switch(pack->opcode)
		{
			case 0:
				break;

			case ServerOP_KeepAlive:
			{
				// ignore this
				break;
			}
			case ServerOP_ZAAuth:
			{
				_log(WEB_INTERFACE__ERROR, "Got authentication from WebInterface when they are already authenticated.");
				break;
			}
			case ServerOP_WIRemoteCall:
			{
				char *id = nullptr;
				char *session_id = nullptr;
				char *method = nullptr;

				id = new char[pack->ReadUInt32() + 1];
				pack->ReadString(id);

				session_id = new char[pack->ReadUInt32() + 1];
				pack->ReadString(session_id);

				method = new char[pack->ReadUInt32() + 1];
				pack->ReadString(method);

				uint32 param_count = pack->ReadUInt32();
				std::vector<std::string> params;
				for(uint32 i = 0; i < param_count; ++i) {
					char *p = new char[pack->ReadUInt32() + 1];
					pack->ReadString(p);
					params.push_back(p);
					safe_delete_array(p);
				}

				if (remote_call_methods.count(method) != 0) {
					auto f = remote_call_methods[method];
					f(method, session_id, id, params);
				}

				safe_delete_array(id);
				safe_delete_array(session_id);
				safe_delete_array(method);
				break;
			}
			case ServerOP_WIClientSessionResponse: {
				uint32 zone_id = pack->ReadUInt32();
				uint32 instance_id = pack->ReadUInt32();
				
				ZoneServer *zs = nullptr;
				if(instance_id != 0) {
					zs = zoneserver_list.FindByInstanceID(instance_id);
				} else {
					zs = zoneserver_list.FindByZoneID(zone_id);
				}

				if(zs) {
					ServerPacket *npack = new ServerPacket(ServerOP_WIClientSessionResponse, pack->size - 8);
					memcpy(npack->pBuffer, pack->pBuffer + 8, pack->size - 8);

					zs->SendPacket(npack);
					safe_delete(npack);
				}

				break;
			}
			default:
			{
				_log(WEB_INTERFACE__ERROR, "Unknown ServerOPcode from WebInterface 0x%04x, size %d", pack->opcode, pack->size);
				DumpPacket(pack->pBuffer, pack->size);
				break;
			}
		}

		delete pack;
	}
	return(true);
}
コード例 #19
0
ファイル: emu_tcp_connection.cpp プロジェクト: jcon321/Server
bool EmuTCPConnection::LineOutQueuePush(char* line) {
	#if defined(GOTFRAGS) && 0
		if (strcmp(line, "**CRASHME**") == 0) {
			int i = 0;
			std::cout << (5 / i) << std::endl;
		}
	#endif
	if(line[0] == '*') {
		if (strcmp(line, "**PACKETMODE**") == 0) {
			MSendQueue.lock();
			safe_delete_array(sendbuf);
			if (TCPMode == modeConsole)
				Send((const uchar*) "\0**PACKETMODE**\r", 16);
			TCPMode = modePacket;
			PacketMode = packetModeLogin;
			EmuTCPNetPacket_Struct* tnps = 0;
			while ((tnps = InModeQueue.pop())) {
				SendPacket(tnps);
				safe_delete_array(tnps);
			}
			MSendQueue.unlock();
			safe_delete_array(line);
			return(true);
		}
		if (strcmp(line, "**PACKETMODEZONE**") == 0) {
			MSendQueue.lock();
			safe_delete_array(sendbuf);
			if (TCPMode == modeConsole)
				Send((const uchar*) "\0**PACKETMODEZONE**\r", 20);
			TCPMode = modePacket;
			PacketMode = packetModeZone;
			EmuTCPNetPacket_Struct* tnps = 0;
			while ((tnps = InModeQueue.pop())) {
				SendPacket(tnps);
				safe_delete_array(tnps);
			}
			MSendQueue.unlock();
			safe_delete_array(line);
			return(true);
		}
		if (strcmp(line, "**PACKETMODELAUNCHER**") == 0) {
			MSendQueue.lock();
			safe_delete_array(sendbuf);
			if (TCPMode == modeConsole)
				Send((const uchar*) "\0**PACKETMODELAUNCHER**\r", 24);
			TCPMode = modePacket;
			PacketMode = packetModeLauncher;
			EmuTCPNetPacket_Struct* tnps = 0;
			while ((tnps = InModeQueue.pop())) {
				SendPacket(tnps);
				safe_delete_array(tnps);
			}
			MSendQueue.unlock();
			safe_delete_array(line);
			return(true);
		}
		if (strcmp(line, "**PACKETMODEUCS**") == 0) {
			MSendQueue.lock();
			safe_delete_array(sendbuf);
			if (TCPMode == modeConsole)
				Send((const uchar*) "\0**PACKETMODEUCS**\r", 19);
			TCPMode = modePacket;
			PacketMode = packetModeUCS;
			EmuTCPNetPacket_Struct* tnps = 0;
			while ((tnps = InModeQueue.pop())) {
				SendPacket(tnps);
				safe_delete_array(tnps);
			}
			MSendQueue.unlock();
			safe_delete_array(line);
			return(true);
		}
		if (strcmp(line, "**PACKETMODEQS**") == 0) {
			MSendQueue.lock();
			safe_delete_array(sendbuf);
			if (TCPMode == modeConsole)
				Send((const uchar*) "\0**PACKETMODEQS**\r", 18);
			TCPMode = modePacket;
			PacketMode = packetModeQueryServ;
			EmuTCPNetPacket_Struct* tnps = 0;
			while ((tnps = InModeQueue.pop())) {
				SendPacket(tnps);
				safe_delete_array(tnps);
			}
			MSendQueue.unlock();
			safe_delete_array(line);
			return(true);
		}
		if (strcmp(line, "**PACKETMODEWI**") == 0) {
			MSendQueue.lock();
			safe_delete_array(sendbuf);
			if (TCPMode == modeConsole)
				Send((const uchar*) "\0**PACKETMODEWI**\r", 18);
			TCPMode = modePacket;
			PacketMode = packetModeWebInterface;
			EmuTCPNetPacket_Struct* tnps = 0;
			while ((tnps = InModeQueue.pop())) {
				SendPacket(tnps);
				safe_delete_array(tnps);
			}
			MSendQueue.unlock();
			safe_delete_array(line);
			return(true);
		}
	}

	return(TCPConnection::LineOutQueuePush(line));
}
コード例 #20
0
ファイル: Adventure.cpp プロジェクト: Vaion/Server
void Adventure::MoveCorpsesToGraveyard()
{
	if(GetTemplate()->graveyard_zone_id == 0)
	{
		return;
	}

	list<uint32> dbid_list;
	list<uint32> charid_list;
	char errbuf[MYSQL_ERRMSG_SIZE];
	char* query = 0;
	MYSQL_RES *result;
	MYSQL_ROW row;

	if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT id, charid FROM player_corpses WHERE instanceid=%d", GetInstanceID()), errbuf, &result)) 
	{
		while((row = mysql_fetch_row(result))) 
		{
			dbid_list.push_back(atoi(row[0]));
			charid_list.push_back(atoi(row[1]));
		}
		mysql_free_result(result);
		safe_delete_array(query);
	}
	else
	{
		LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query, errbuf);
		safe_delete_array(query);
	}

	list<uint32>::iterator iter = dbid_list.begin();
	while(iter != dbid_list.end())
	{
		float x = GetTemplate()->graveyard_x + MakeRandomFloat(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius);
		float y = GetTemplate()->graveyard_y + MakeRandomFloat(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius);
		float z = GetTemplate()->graveyard_z;
		if(database.RunQuery(query,MakeAnyLenString(&query, "UPDATE player_corpses SET zoneid=%d, instanceid=0, x=%f, y=%f, z=%f WHERE instanceid=%d", 
			GetTemplate()->graveyard_zone_id, x, y, z, GetInstanceID()), errbuf)) 
		{
			safe_delete_array(query);
		}
		else
		{
			LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query, errbuf);
			safe_delete_array(query);
		}
		iter++;
	}

	iter = dbid_list.begin();
	list<uint32>::iterator c_iter = charid_list.begin();
	while(iter != dbid_list.end())
	{
		ServerPacket* pack = new ServerPacket(ServerOP_DepopAllPlayersCorpses, sizeof(ServerDepopAllPlayersCorpses_Struct));
		ServerDepopAllPlayersCorpses_Struct *dpc = (ServerDepopAllPlayersCorpses_Struct*)pack->pBuffer;
		dpc->CharacterID = (*c_iter);
		dpc->InstanceID = 0;
		dpc->ZoneID = GetTemplate()->graveyard_zone_id;
		zoneserver_list.SendPacket(0, GetInstanceID(), pack);
		delete pack;

		pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct));
		SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer;
		spc->player_corpse_id = (*iter);
		spc->zone_id = GetTemplate()->graveyard_zone_id;

		zoneserver_list.SendPacket(spc->zone_id, 0, pack);
		delete pack;
		iter++;
		c_iter++;
	}
}
コード例 #21
0
ファイル: emu_tcp_connection.cpp プロジェクト: jcon321/Server
bool EmuTCPConnection::ProcessReceivedDataAsOldPackets(char* errbuf) {
	int32 base = 0;
	int32 size = 4;
	uchar* buffer;
	ServerPacket* pack = 0;
	while ((recvbuf_used - base) >= size) {
		buffer = &recvbuf[base];
		memcpy(&size, &buffer[2], 2);
		if (size >= MaxTCPReceiveBuffferSize) {
#if TCPN_DEBUG_Memory >= 1
			std::cout << "TCPConnection[" << GetID() << "]::ProcessReceivedDataAsPackets(): size[" << size << "] >= MaxTCPReceiveBuffferSize" << std::endl;
#endif
			if (errbuf)
				snprintf(errbuf, TCPConnection_ErrorBufferSize, "EmuTCPConnection::ProcessReceivedDataAsPackets(): size >= MaxTCPReceiveBuffferSize");
			return false;
		}
		if ((recvbuf_used - base) >= size) {
			// ok, we got enough data to make this packet!
			pack = new ServerPacket;
			memcpy(&pack->opcode, &buffer[0], 2);
			pack->size = size - 4;
/*			if () { // TODO: Checksum or size check or something similar
				// Datastream corruption, get the hell outta here!
				delete pack;
				return false;
			}*/
			if (pack->size > 0) {
				pack->pBuffer = new uchar[pack->size];
				memcpy(pack->pBuffer, &buffer[4], pack->size);
			}
			if (pack->opcode == 0) {
				// keepalive, no need to process
				safe_delete(pack);
			}
			else {
				#if TCPN_LOG_PACKETS >= 1
					if (pack && pack->opcode != 0) {
						struct in_addr	in;
						in.s_addr = GetrIP();
						CoutTimestamp(true);
						std::cout << ": Logging incoming TCP OldPacket. OPCode: 0x" << std::hex << std::setw(4) << std::setfill('0') << pack->opcode << std::dec << ", size: " << std::setw(5) << std::setfill(' ') << pack->size << " " << inet_ntoa(in) << ":" << GetrPort() << std::endl;
						#if TCPN_LOG_PACKETS == 2
							if (pack->size >= 32)
								DumpPacket(pack->pBuffer, 32);
							else
								DumpPacket(pack);
						#endif
						#if TCPN_LOG_PACKETS >= 3
							DumpPacket(pack);
						#endif
					}
				#endif
				OutQueuePush(pack);
			}
			base += size;
			size = 4;
		}
	}
	if (base != 0) {
		if (base >= recvbuf_used) {
			safe_delete_array(recvbuf);
		}
		else {
			uchar* tmpbuf = new uchar[recvbuf_size - base];
			memcpy(tmpbuf, &recvbuf[base], recvbuf_used - base);
			safe_delete_array(recvbuf);
			recvbuf = tmpbuf;
			recvbuf_used -= base;
			recvbuf_size -= base;
		}
	}
	return true;
}
コード例 #22
0
ファイル: WndNotice.cpp プロジェクト: careysky/FlyFF
void CWndInfoNotice::OnInitialUpdate() 
{ 
	CWndNeuz::OnInitialUpdate(); 
	// 여기에 코딩하세요

	CWndButton* pWndCheck = (CWndButton*)GetDlgItem( WIDC_CHECK1 );
	pWndCheck->SetCheck( !g_Option.m_bNotice );
	CWndText* pWndText = (CWndText*)GetDlgItem( WIDC_TEXT1 );

#ifdef __YNOTICE_UNI1026
	CString strnotice;
	strnotice = GetLangFileName( ::GetLanguage(), FILE_NOTICE );
		
	CScript scanner;
	if( scanner.Load( "Client\\"+strnotice ) == FALSE )
		return;
	
	pWndText->m_string.AddParsingString( scanner.m_pProg  );
	pWndText->ResetString();
#else //__YNOTICE_UNI1026
	CFileStatus fileStatus;
	
	CString strnotice;
	strnotice = GetLangFileName( ::GetLanguage(), FILE_NOTICE );
	
	if( CFile::GetStatus( "Client\\"+strnotice, fileStatus ) == TRUE )
	{
		if( g_Option.m_tNoticeTime != fileStatus.m_mtime.GetTime() )
			g_Option.m_tNoticeTime = static_cast< time_t >( fileStatus.m_mtime.GetTime() );

		CFileIO file;

		strnotice = GetLangFileName( ::GetLanguage(), FILE_NOTICE );
	
		if(::GetLanguage() == LANG_VTN)
		{
			if( file.Open( "Client\\"+strnotice, "rb" ) )
			{
				int nLength = file.GetLength();
				TCHAR* pChar = new TCHAR[ nLength + 2 ];
				file.Read( pChar, nLength );
				*(pChar + nLength ) = '\0';
				*(pChar + nLength + 1 ) = '\0';

				char* lpMultiByte = new char[ nLength + 2 ];

				int nResult = WideCharToMultiByteEx( g_codePage, 0, 
					                               (LPWSTR)(pChar+2), -1, 
						                           lpMultiByte, nLength, 
												   NULL, NULL );

				if( nResult > 0 )
				{
					lpMultiByte[nResult-1] = 0;
					pWndText->m_string.AddParsingString( lpMultiByte );
					pWndText->ResetString();
				}
				safe_delete_array(pChar);
				safe_delete_array(lpMultiByte);
			}
		}
		else
		{
			if( file.Open( "Client\\"+strnotice, "rb" ) )
			{
				int nLength = file.GetLength();
				TCHAR* pChar = new TCHAR[ nLength + 1];
				file.Read( pChar, nLength );
				pChar[ nLength ] = 0;
				//pWndText->SetString( pChar );
				pWndText->m_string.AddParsingString( pChar );
				pWndText->ResetString();
				safe_delete( pChar );
			}
		}
	}
#endif //__YNOTICE_UNI1026

	// 윈도를 중앙으로 옮기는 부분.
	CRect rectRoot = m_pWndRoot->GetLayoutRect();
	CRect rectWindow = GetWindowRect();
	CPoint point( rectRoot.right - rectWindow.Width(), 110 );
	Move( point );
	MoveParentCenter();

/////////////////////////////////////////////////////////////////////////////////////////
	int nCount = 0;	
	CScript script;
	if( script.Load(MakePath(DIR_THEME, "TexBannerList.inc" )) )
	{
		int nLang;
		nLang = script.GetNumber();
		do 
		{
			if( nLang == ::GetLanguage() )
			{
				script.GetToken();
				
				nCount = atoi( script.token );
				
				script.GetToken();				
				
				for( int i=0; i<nCount; i++ )
				{
					CString addStr = script.token;
					m_vecStrBanner.push_back( addStr );
					script.GetToken();
				}
				
				if( nCount <= 0 )
				{
					Error( "TexBannerList.inc의 갯수가 0이다" );
					return;
				}
				
				break;
			}
			else
				script.GetLastFull();

			nLang = script.GetNumber();
		} while( script.tok != FINISHED );		
	}
	
	SAFE_DELETE( m_atexPannel );
	if( nCount > 0 )
	{
		m_atexPannel = new IMAGE;
		LoadImage( MakePath( DIR_THEME, m_vecStrBanner[xRandom(nCount)] ), m_atexPannel );
		AdjustWndBase();	
	}
/////////////////////////////////////////////////////////////////////////////////////////	
} 
コード例 #23
0
ファイル: zoning.cpp プロジェクト: Corysia/Server
void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm) {
	bool ReadyToZone = true;
	int iZoneNameLength = 0;
	const char*	pShortZoneName = nullptr;
	char* pZoneName = nullptr;

	pShortZoneName = database.GetZoneName(zoneID);
	database.GetZoneLongName(pShortZoneName, &pZoneName);

	SetPortExemption(true);

	if(!pZoneName) {
		Message(13, "Invalid zone number specified");
		safe_delete_array(pZoneName);
		return;
	}
	iZoneNameLength = strlen(pZoneName);

	switch(zm) {
		case EvacToSafeCoords:
		case ZoneToSafeCoords:
			x = zone->safe_x();
			y = zone->safe_y();
			z = zone->safe_z();
			SetHeading(heading);
			break;
		case GMSummon:
			zonesummon_x = x_pos = x;
			zonesummon_y = y_pos = y;
			zonesummon_z = z_pos = z;
			SetHeading(heading);

			zonesummon_id = zoneID;
			zonesummon_ignorerestrictions = 1;
			break;
		case ZoneSolicited:
			zonesummon_x = x;
			zonesummon_y = y;
			zonesummon_z = z;
			SetHeading(heading);

			zonesummon_id = zoneID;
			zonesummon_ignorerestrictions = ignorerestrictions;
			break;
		case GateToBindPoint:
			x = x_pos = m_pp.binds[0].x;
			y = y_pos = m_pp.binds[0].y;
			z = z_pos = m_pp.binds[0].z;
			heading = m_pp.binds[0].heading;
			break;
		case ZoneToBindPoint:
			x = x_pos = m_pp.binds[0].x;
			y = y_pos = m_pp.binds[0].y;
			z = z_pos = m_pp.binds[0].z;
			heading = m_pp.binds[0].heading;

			zonesummon_ignorerestrictions = 1;
			LogFile->write(EQEMuLog::Debug, "Player %s has died and will be zoned to bind point in zone: %s at LOC x=%f, y=%f, z=%f, heading=%f", GetName(), pZoneName, m_pp.binds[0].x, m_pp.binds[0].y, m_pp.binds[0].z, m_pp.binds[0].heading);
			break;
		case SummonPC:
			zonesummon_x = x_pos = x;
			zonesummon_y = y_pos = y;
			zonesummon_z = z_pos = z;
			SetHeading(heading);
			break;
		case Rewind:
			LogFile->write(EQEMuLog::Debug, "%s has requested a /rewind from %f, %f, %f, to %f, %f, %f in %s", GetName(), x_pos, y_pos, z_pos, rewind_x, rewind_y, rewind_z, zone->GetShortName());
			zonesummon_x = x_pos = x;
			zonesummon_y = y_pos = y;
			zonesummon_z = z_pos = z;
			SetHeading(heading);
			break;
		default:
			LogFile->write(EQEMuLog::Error, "Client::ZonePC() received a reguest to perform an unsupported client zone operation.");
			ReadyToZone = false;
			break;
	}

	if(ReadyToZone) {
		zone_mode = zm;
		if(zm == ZoneToBindPoint) {
			EQApplicationPacket* outapp = new EQApplicationPacket(OP_ZonePlayerToBind, sizeof(ZonePlayerToBind_Struct) + iZoneNameLength);
			ZonePlayerToBind_Struct* gmg = (ZonePlayerToBind_Struct*) outapp->pBuffer;

			// If we are SoF and later and are respawning from hover, we want the real zone ID, else zero to use the old hack.
			//
			if((GetClientVersionBit() & BIT_SoFAndLater) && (!RuleB(Character, RespawnFromHover) || !IsHoveringForRespawn()))
				gmg->bind_zone_id = 0;
			else
				gmg->bind_zone_id = zoneID;

			gmg->x = x;
			gmg->y = y;
			gmg->z = z;
			gmg->heading = heading;
			strcpy(gmg->zone_name, pZoneName);

			outapp->priority = 6;
			FastQueuePacket(&outapp);
			safe_delete(outapp);
		}
		else if(zm == ZoneSolicited || zm == ZoneToSafeCoords) {
			EQApplicationPacket* outapp = new EQApplicationPacket(OP_RequestClientZoneChange, sizeof(RequestClientZoneChange_Struct));
			RequestClientZoneChange_Struct* gmg = (RequestClientZoneChange_Struct*) outapp->pBuffer;

			gmg->zone_id = zoneID;
			gmg->x = x;
			gmg->y = y;
			gmg->z = z;
			gmg->heading = heading;
			gmg->instance_id = instance_id;
			gmg->type = 0x01;				//an observed value, not sure of meaning

			outapp->priority = 6;
			FastQueuePacket(&outapp);
			safe_delete(outapp);
		}
		else if(zm == EvacToSafeCoords) {
			EQApplicationPacket* outapp = new EQApplicationPacket(OP_RequestClientZoneChange, sizeof(RequestClientZoneChange_Struct));
			RequestClientZoneChange_Struct* gmg = (RequestClientZoneChange_Struct*) outapp->pBuffer;

			// if we are in the same zone we want to evac to, client will not send OP_ZoneChange back to do an actual
			// zoning of the client, so we have to send a viable zoneid that the client *could* zone to to make it believe
			// we are leaving the zone, even though we are not. We have to do this because we are missing the correct op code
			// and struct that should be used for evac/succor.
			// 213 is Plane of War
			// 76 is orignial Plane of Hate
			// WildcardX 27 January 2008. Tested this for 6.2 and Titanium clients.

			if(this->GetZoneID() == 1)
				gmg->zone_id = 2;
			else if(this->GetZoneID() == 2)
				gmg->zone_id = 1;
			else
				gmg->zone_id = 1;

			gmg->x = x;
			gmg->y = y;
			gmg->z = z;
			gmg->heading = heading;
			gmg->instance_id = instance_id;
			gmg->type = 0x01;				// '0x01' was an observed value for the type field, not sure of meaning

			// we hide the real zoneid we want to evac/succor to here
			zonesummon_id = zoneID;

			outapp->priority = 6;
			FastQueuePacket(&outapp);
			safe_delete(outapp);
		}
		else {
			if(zoneID == GetZoneID()) {
				//properly handle proximities
				entity_list.ProcessMove(this, x_pos, y_pos, z_pos);
				proximity_x = x_pos;
				proximity_y = y_pos;
				proximity_z = z_pos;

				//send out updates to people in zone.
				SendPosition();
			}

			EQApplicationPacket* outapp = new EQApplicationPacket(OP_RequestClientZoneChange, sizeof(RequestClientZoneChange_Struct));
			RequestClientZoneChange_Struct* gmg = (RequestClientZoneChange_Struct*) outapp->pBuffer;

			gmg->zone_id = zoneID;
			gmg->x = x;
			gmg->y = y;
			gmg->z = z;
			gmg->heading = heading;
			gmg->instance_id = instance_id;
			gmg->type = 0x01;	//an observed value, not sure of meaning
			outapp->priority = 6;
			FastQueuePacket(&outapp);
			safe_delete(outapp);
		}

		_log(NET__DEBUG, "Player %s has requested a zoning to LOC x=%f, y=%f, z=%f, heading=%f in zoneid=%i", GetName(), x, y, z, heading, zoneID);
		//Clear zonesummon variables if we're zoning to our own zone
		//Client wont generate a zone change packet to the server in this case so
		//They aren't needed and it keeps behavior on next zone attempt from being undefined.
		if(zoneID == zone->GetZoneID() && instance_id == zone->GetInstanceID())
		{
			if(zm != EvacToSafeCoords && zm != ZoneToSafeCoords && zm != ZoneToBindPoint)
			{
				zonesummon_x = 0;
				zonesummon_y = 0;
				zonesummon_z = 0;
				zonesummon_id = 0;
				zonesummon_ignorerestrictions = 0;
				zone_mode = ZoneUnsolicited;
			}
		}
	}

	safe_delete_array(pZoneName);
}
コード例 #24
0
bool SharedMemory::LoadItems(){
	char errbuf[MYSQL_ERRMSG_SIZE];
	char *query = 0;
	MYSQL_RES *result;
	MYSQL_ROW row;
	int id;
	query = new char[256];
	strcpy(query, "SELECT MAX(id) FROM items");

	EQC::Common::PrintF(CP_SHAREDMEMORY, "Loading items... ");
	if (Database::Instance()->RunQuery(query, strlen(query), errbuf, &result)) {
		safe_delete(query);
		row = mysql_fetch_row(result);
		if (row != 0 && row[0] > 0)
		{ 
			getPtr()->max_item = atoi(row[0]);
			if (getPtr()->max_item >= MAXITEMID) {
				EQC::Common::PrintF(CP_SHAREDMEMORY, "bool SharedMemory::LoadItems(): More items than MAXITEMID. Change constant in SharedMemory.hpp");
				return false;
			}
			memset(&getPtr()->item_array, 0, sizeof(getPtr()->item_array));
			mysql_free_result(result);

			MakeAnyLenString(&query, "SELECT id,raw_data FROM items");

			if (Database::Instance()->RunQuery(query, strlen(query), errbuf, &result))
			{
				safe_delete_array(query);//delete[] query;
				while(row = mysql_fetch_row(result))
				{
					unsigned long* lengths;
					lengths = mysql_fetch_lengths(result);
					if (lengths[1] == sizeof(Item_Struct))
					{
						id = atoi(row[0]);
						memcpy(&getPtr()->item_array[id], row[1], sizeof(Item_Struct));
						//Yeahlight: Client item exceptions
						if(getPtr()->item_array[id].type == 0)
						{
							//Yeahlight: Remove 'BST' (01000000 00000000) from item classes as long as the list does not compute to 'ALL' (01111111 11111111)
							if(getPtr()->item_array[id].common.classes - 16384 >= 0 && getPtr()->item_array[id].common.classes != 32767)
								getPtr()->item_array[id].common.classes -= 16384;
							//Yeahlight: Remove 'VAH' (00100000 00000000) from item races as long as the list does not compute to 'ALL' (00111111 11111111)
							if(getPtr()->item_array[id].common.normal.races - 8192 >= 0 && getPtr()->item_array[id].common.normal.races != 16383)
								getPtr()->item_array[id].common.normal.races -= 8192;
							//Yeahlight: Our client cannot handle H2H skill weapons, so flag them as 1HB
							if(getPtr()->item_array[id].common.itemType == ItemTypeHand2Hand)
								getPtr()->item_array[id].common.itemType = ItemType1HB;
							//Yeahlight: There will be no gear with recommended levels on the server, so zero out this field
							if(getPtr()->item_array[id].common.recommendedLevel != 0)
								getPtr()->item_array[id].common.recommendedLevel = 0;
							//Yeahlight: This purges focus effects from our items
							if(getPtr()->item_array[id].common.click_effect_id >= 2330 && getPtr()->item_array[id].common.click_effect_id <= 2374)
							{
								getPtr()->item_array[id].common.click_effect_id = 0;
								getPtr()->item_array[id].common.spell_effect_id = 0;
								getPtr()->item_array[id].common.charges = 0;
								getPtr()->item_array[id].common.normal.click_effect_type = 0;
								getPtr()->item_array[id].common.effecttype = 0;
								getPtr()->item_array[id].common.clicktype = 0;
							}
						}
						//Yeahlight: Client container exceptions
						else if(getPtr()->item_array[id].type == 1)
						{
							//Tazadar : We clean this or the client crashes or bag are full of shit
							memset(&getPtr()->item_array[id].common.level,0x00,69*sizeof(int8));
							memset(&getPtr()->item_array[id].unknown0144[0],0x00,68*sizeof(int8));
						}
						//Yeahlight: Client book exceptions
						else if(getPtr()->item_array[id].type == 2)
						{

						}
					}
					else
					{
						cout << "Invalid items in database..." << endl;
					}
					Sleep(0);
				}
				mysql_free_result(result);
			}
			else {
				cerr << "Error in PopulateZoneLists query '" << query << "' " << errbuf << endl;
				safe_delete_array(query);//delete[] query;
				return false;
			}
		}
		else {
			mysql_free_result(result);
		}
	}
	else {
		cerr << "Error in PopulateZoneLists query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);//delete[] query;
		return false;
	}
	EQC::Common::PrintF(CP_SHAREDMEMORY, "Item loading finished.");
	return true;
}
コード例 #25
0
ファイル: pets.cpp プロジェクト: Corysia/Server
// Split from the basic MakePet to allow backward compatiblity with existing code while also
// making it possible for petpower to be retained without the focus item having to
// stay equipped when the character zones. petpower of -1 means that the currently equipped petfocus
// of a client is searched for and used instead.
void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
		const char *petname, float in_size) {
	// Sanity and early out checking first.
	if(HasPet() || pettype == nullptr)
		return;

	int16 act_power = 0; // The actual pet power we'll use.
	if (petpower == -1) {
		if (this->IsClient()) {
			act_power = CastToClient()->GetFocusEffect(focusPetPower, spell_id);
			act_power = CastToClient()->mod_pet_power(act_power, spell_id);
		}
	}
	else if (petpower > 0)
		act_power = petpower;

	// optional rule: classic style variance in pets. Achieve this by
	// adding a random 0-4 to pet power, since it only comes in increments
	// of five from focus effects.

	//lookup our pets table record for this type
	PetRecord record;
	if(!database.GetPoweredPetEntry(pettype, act_power, &record)) {
		Message(13, "Unable to find data for pet %s", pettype);
		LogFile->write(EQEMuLog::Error, "Unable to find data for pet %s, check pets table.", pettype);
		return;
	}

	//find the NPC data for the specified NPC type
	const NPCType *base = database.GetNPCType(record.npc_type);
	if(base == nullptr) {
		Message(13, "Unable to load NPC data for pet %s", pettype);
		LogFile->write(EQEMuLog::Error, "Unable to load NPC data for pet %s (NPC ID %d), check pets and npc_types tables.", pettype, record.npc_type);
		return;
	}

	//we copy the npc_type data because we need to edit it a bit
	NPCType *npc_type = new NPCType;
	memcpy(npc_type, base, sizeof(NPCType));

	// If pet power is set to -1 in the DB, use stat scaling
	if (this->IsClient() && record.petpower == -1)
	{
		float scale_power = (float)act_power / 100.0f;
		if(scale_power > 0)
		{
			npc_type->max_hp *= (1 + scale_power);
			npc_type->cur_hp = npc_type->max_hp;
			npc_type->AC *= (1 + scale_power);
			npc_type->level += 1 + ((int)act_power / 25); // gains an additional level for every 25 pet power
			npc_type->min_dmg = (npc_type->min_dmg * (1 + (scale_power / 2)));
			npc_type->max_dmg = (npc_type->max_dmg * (1 + (scale_power / 2)));
			npc_type->size *= (1 + (scale_power / 2));
		}
		record.petpower = act_power;
	}

	//Live AA - Elemental Durability
	int16 MaxHP = aabonuses.PetMaxHP + itembonuses.PetMaxHP + spellbonuses.PetMaxHP;

	if (MaxHP){
		npc_type->max_hp += (npc_type->max_hp*MaxHP)/100;
		npc_type->cur_hp = npc_type->max_hp;
	}

	//TODO: think about regen (engaged vs. not engaged)

	// Pet naming:
	// 0 - `s pet
	// 1 - `s familiar
	// 2 - `s Warder
	// 3 - Random name if client, `s pet for others
	// 4 - Keep DB name


	if (petname != nullptr) {
		// Name was provided, use it.
		strn0cpy(npc_type->name, petname, 64);
	} else if (record.petnaming == 0) {
		strcpy(npc_type->name, this->GetCleanName());
		npc_type->name[25] = '\0';
		strcat(npc_type->name, "`s_pet");
	} else if (record.petnaming == 1) {
		strcpy(npc_type->name, this->GetName());
		npc_type->name[19] = '\0';
		strcat(npc_type->name, "`s_familiar");
	} else if (record.petnaming == 2) {
		strcpy(npc_type->name, this->GetName());
		npc_type->name[21] = 0;
		strcat(npc_type->name, "`s_Warder");
	} else if (record.petnaming == 4) {
		// Keep the DB name
	} else if (record.petnaming == 3 && IsClient()) {
		strcpy(npc_type->name, GetRandPetName());
	} else {
		strcpy(npc_type->name, this->GetCleanName());
		npc_type->name[25] = '\0';
		strcat(npc_type->name, "`s_pet");
	}

	//handle beastlord pet appearance
	if(record.petnaming == 2)
	{
		switch(GetBaseRace())
		{
		case VAHSHIR:
			npc_type->race = TIGER;
			npc_type->size *= 0.8f;
			break;
		case TROLL:
			npc_type->race = ALLIGATOR;
			npc_type->size *= 2.5f;
			break;
		case OGRE:
			npc_type->race = BEAR;
			npc_type->texture = 3;
			npc_type->gender = 2;
			break;
		case BARBARIAN:
			npc_type->race = WOLF;
			npc_type->texture = 2;
			break;
		case IKSAR:
			npc_type->race = WOLF;
			npc_type->texture = 0;
			npc_type->gender = 1;
			npc_type->size *= 2.0f;
			npc_type->luclinface = 0;
			break;
		default:
			npc_type->race = WOLF;
			npc_type->texture = 0;
		}
	}

	// handle monster summoning pet appearance
	if(record.monsterflag) {
		char errbuf[MYSQL_ERRMSG_SIZE];
		char* query = 0;
		MYSQL_RES *result = nullptr;
		MYSQL_ROW row = nullptr;
		uint32 monsterid;

		// get a random npc id from the spawngroups assigned to this zone
		if (database.RunQuery(query,	MakeAnyLenString(&query,
			"SELECT npcID FROM (spawnentry INNER JOIN spawn2 ON spawn2.spawngroupID = spawnentry.spawngroupID) "
			"INNER JOIN npc_types ON npc_types.id = spawnentry.npcID "
			"WHERE spawn2.zone = '%s' AND npc_types.bodytype NOT IN (11, 33, 66, 67) "
			"AND npc_types.race NOT IN (0,1,2,3,4,5,6,7,8,9,10,11,12,44,55,67,71,72,73,77,78,81,90,92,93,94,106,112,114,127,128,130,139,141,183,236,237,238,239,254,266,329,330,378,379,380,381,382,383,404,522) "
			"ORDER BY RAND() LIMIT 1",	zone->GetShortName()), errbuf, &result))
		{
			row = mysql_fetch_row(result);
			if (row)
				monsterid = atoi(row[0]);
			else
				monsterid = 567;	// since we don't have any monsters, just make it look like an earth pet for now
		}
		else {	// if the database query failed
			LogFile->write(EQEMuLog::Error, "Error querying database for monster summoning pet in zone %s (%s)", zone->GetShortName(), errbuf);
			monsterid = 567;
		}

		// give the summoned pet the attributes of the monster we found
		const NPCType* monster = database.GetNPCType(monsterid);
		if(monster) {
			npc_type->race = monster->race;
			npc_type->size = monster->size;
			npc_type->texture = monster->texture;
			npc_type->gender = monster->gender;
			npc_type->luclinface = monster->luclinface;
			npc_type->helmtexture = monster->helmtexture;
		}
		else {
			LogFile->write(EQEMuLog::Error, "Error loading NPC data for monster summoning pet (NPC ID %d)", monsterid);
		}

		safe_delete_array(query);
	}

	//this takes ownership of the npc_type data
	Pet *npc = new Pet(npc_type, this, (PetType)record.petcontrol, spell_id, record.petpower);

	// Now that we have an actual object to interact with, load
	// the base items for the pet. These are always loaded
	// so that a rank 1 suspend minion does not kill things
	// like the special back items some focused pets may receive.
	uint32 petinv[MAX_WORN_INVENTORY];
	memset(petinv, 0, sizeof(petinv));
	const Item_Struct *item = 0;

	if (database.GetBasePetItems(record.equipmentset, petinv)) {
		for (int i=0; i<MAX_WORN_INVENTORY; i++)
			if (petinv[i]) {
				item = database.GetItem(petinv[i]);
				npc->AddLootDrop(item, &npc->itemlist, 0, 1, 127, true, true);
			}
	}

	// finally, override size if one was provided
	if (in_size > 0.0f)
		npc->size = in_size;

	entity_list.AddNPC(npc, true, true);
	SetPetID(npc->GetID());
	// We need to handle PetType 5 (petHatelist), add the current target to the hatelist of the pet
}
コード例 #26
0
ファイル: tcp_connection.cpp プロジェクト: aaronze/Server
void TCPConnection::AsyncConnect(const char* irAddress, uint16 irPort) {
	safe_delete_array(charAsyncConnect);
	charAsyncConnect = new char[strlen(irAddress) + 1];
	strcpy(charAsyncConnect, irAddress);
	AsyncConnect((uint32) 0, irPort);
}
コード例 #27
0
ファイル: forage.cpp プロジェクト: josheb/Server
uint32 ZoneDatabase::GetZoneFishing(uint32 ZoneID, uint8 skill, uint32 &npc_id, uint8 &npc_chance)
{
	char errbuf[MYSQL_ERRMSG_SIZE];
	char *query = 0;
	MYSQL_RES *result;
	MYSQL_ROW row;

	uint8 index = 0;
	uint32 item[50];
	uint32 chance[50];
	uint32 npc_ids[50];
	uint32 npc_chances[50];
	uint32 chancepool = 0;
	uint32 ret = 0;

	for (int c=0; c<50; c++) {
		item[c]=0;
		chance[c]=0;
	}

	if (RunQuery(query, MakeAnyLenString(&query, "SELECT itemid,chance,npc_id,npc_chance FROM fishing WHERE (zoneid= '%i' || zoneid = 0) and skill_level <= '%i'",ZoneID, skill ), errbuf, &result))
	{
		safe_delete_array(query);
		while ((row = mysql_fetch_row(result))&&(index<50)) {
			item[index] = atoi(row[0]);
			chance[index] = atoi(row[1])+chancepool;
			chancepool = chance[index];

			npc_ids[index] = atoi(row[2]);
			npc_chances[index] = atoi(row[3]);
			index++;
		}

		mysql_free_result(result);
	}
	else {
		std::cerr << "Error in Fishing query '" << query << "' " << errbuf << std::endl;
		safe_delete_array(query);
		return 0;
	}

	npc_id = 0;
	npc_chance = 0;
	if (index>0) {
		uint32 random = MakeRandomInt(1, chancepool);
		for (int i = 0; i < index; i++)
		{
			if (random <= chance[i])
			{
				ret = item[i];
				npc_id = npc_ids[i];
				npc_chance = npc_chances[i];
				break;
			}
		}
	} else {
		ret = 0;
	}

	return ret;
}
コード例 #28
0
ファイル: tcp_connection.cpp プロジェクト: aaronze/Server
/* This is always called from an IO thread. Either the server socket's thread, or a
 * special thread we create when we make an outbound connection. */
bool TCPConnection::Process() {
	char errbuf[TCPConnection_ErrorBufferSize];
	switch(GetState()) {
	case TCPS_Ready:
	case TCPS_Connecting:
		if (ConnectionType == Outgoing) {
			if (GetAsyncConnect()) {
				if (charAsyncConnect)
					rIP = ResolveIP(charAsyncConnect);
				ConnectIP(rIP, rPort);
			}
		}
		return(true);

	case TCPS_Connected:
		// only receive data in the connected state, no others...
		if (!RecvData(errbuf)) {
			struct in_addr	in;
			in.s_addr = GetrIP();
			//std::cout << inet_ntoa(in) << ":" << GetrPort() << ": " << errbuf << std::endl;
			return false;
		}
		/* we break to do the send */
		break;

	case TCPS_Disconnecting: {
		//waiting for any sending data to go out...
		MSendQueue.lock();
		if(sendbuf) {
			if(sendbuf_used > 0) {
				//something left to send, keep processing...
				MSendQueue.unlock();
				break;
			}
			//else, send buffer is empty.
			safe_delete_array(sendbuf);
		} //else, no send buffer, we are done.
		MSendQueue.unlock();
	}
		/* Fallthrough */

	case TCPS_Disconnected:
		FinishDisconnect();
		MRunLoop.lock();
		pRunLoop = false;
		MRunLoop.unlock();
//		SetState(TCPS_Ready);	//reset the state in case they want to use it again...
		return(false);

	case TCPS_Closing:
		//I dont understand this state...

	case TCPS_Error:
		MRunLoop.lock();
		pRunLoop = false;
		MRunLoop.unlock();
		return(false);
	}

	/* we get here in connected or disconnecting with more data to send */

	bool sent_something = false;
	if (!SendData(sent_something, errbuf)) {
		struct in_addr	in;
		in.s_addr = GetrIP();
		std::cout << inet_ntoa(in) << ":" << GetrPort() << ": " << errbuf << std::endl;
		return false;
	}

	return true;
}
コード例 #29
0
ファイル: clientlist.cpp プロジェクト: Outakyoutou/Server
void ClientList::SendWhoAll(uint32 fromid,const char* to, int16 admin, Who_All_Struct* whom, WorldTCPConnection* connection) {
	try{
	LinkedListIterator<ClientListEntry*> iterator(clientlist);
	LinkedListIterator<ClientListEntry*> countclients(clientlist);
	ClientListEntry* cle = 0;
	ClientListEntry* countcle = 0;
	//char tmpgm[25] = "";
	//char accinfo[150] = "";
	char line[300] = "";
	//char tmpguild[50] = "";
	//char LFG[10] = "";
	//uint32 x = 0;
	int whomlen = 0;
	if (whom) {
		whomlen = strlen(whom->whom);
		if(whom->wrace == 0x001A) // 0x001A is the old Froglok race number and is sent by the client for /who all froglok
			whom->wrace = FROGLOK; // This is what EQEmu uses for the Froglok Race number.
	}

	char* output = 0;
	uint32 outsize = 0, outlen = 0;
	uint32 totalusers=0;
	uint32 totallength=0;
	AppendAnyLenString(&output, &outsize, &outlen, "Players on server:");
	if (connection->IsConsole())
		AppendAnyLenString(&output, &outsize, &outlen, "\r\n");
	else
		AppendAnyLenString(&output, &outsize, &outlen, "\n");
	countclients.Reset();
	while(countclients.MoreElements()){
		countcle = countclients.GetData();
		const char* tmpZone = database.GetZoneName(countcle->zone());
		if (
	(countcle->Online() >= CLE_Status_Zoning) &&
	(!countcle->GetGM() || countcle->Anon() != 1 || admin >= countcle->Admin()) &&
	(whom == 0 || (
		((countcle->Admin() >= 80 && countcle->GetGM()) || whom->gmlookup == 0xFFFF) &&
		(whom->lvllow == 0xFFFF || (countcle->level() >= whom->lvllow && countcle->level() <= whom->lvlhigh && (countcle->Anon()==0 || admin > countcle->Admin()))) &&
		(whom->wclass == 0xFFFF || (countcle->class_() == whom->wclass && (countcle->Anon()==0 || admin > countcle->Admin()))) &&
		(whom->wrace == 0xFFFF || (countcle->race() == whom->wrace && (countcle->Anon()==0 || admin > countcle->Admin()))) &&
		(whomlen == 0 || (
			(tmpZone != 0 && strncasecmp(tmpZone, whom->whom, whomlen) == 0) ||
			strncasecmp(countcle->name(),whom->whom, whomlen) == 0 ||
			(strncasecmp(guild_mgr.GetGuildName(countcle->GuildID()), whom->whom, whomlen) == 0) ||
			(admin >= 100 && strncasecmp(countcle->AccountName(), whom->whom, whomlen) == 0)
		))
	))
) {
			if((countcle->Anon()>0 && admin>=countcle->Admin() && admin>0) || countcle->Anon()==0 ){
				totalusers++;
				if(totalusers<=20 || admin>=100)
					totallength=totallength+strlen(countcle->name())+strlen(countcle->AccountName())+strlen(guild_mgr.GetGuildName(countcle->GuildID()))+5;
			}
			else if((countcle->Anon()>0 && admin<=countcle->Admin()) || (countcle->Anon()==0 && !countcle->GetGM())) {
				totalusers++;
				if(totalusers<=20 || admin>=100)
					totallength=totallength+strlen(countcle->name())+strlen(guild_mgr.GetGuildName(countcle->GuildID()))+5;
			}
		}
		countclients.Advance();
	}
	uint32 plid=fromid;
	uint32 playerineqstring=5001;
	const char line2[]="---------------------------";
	uint8 unknown35=0x0A;
	uint32 unknown36=0;
	uint32 playersinzonestring=5028;
	if(totalusers>20 && admin<100){
		totalusers=20;
		playersinzonestring=5033;
	}
	else if(totalusers>1)
		playersinzonestring=5036;
	uint32 unknown44[2];
	unknown44[0]=0;
	unknown44[1]=0;
	uint32 unknown52=totalusers;
	uint32 unknown56=1;
	auto pack2 = new ServerPacket(ServerOP_WhoAllReply, 64 + totallength + (49 * totalusers));
	memset(pack2->pBuffer,0,pack2->size);
	uchar *buffer=pack2->pBuffer;
	uchar *bufptr=buffer;
	//memset(buffer,0,pack2->size);
	memcpy(bufptr,&plid, sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&playerineqstring, sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&line2, strlen(line2));
	bufptr+=strlen(line2);
	memcpy(bufptr,&unknown35, sizeof(uint8));
	bufptr+=sizeof(uint8);
	memcpy(bufptr,&unknown36, sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&playersinzonestring, sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&unknown44[0], sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&unknown44[1], sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&unknown52, sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&unknown56, sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&totalusers, sizeof(uint32));
	bufptr+=sizeof(uint32);

	iterator.Reset();
	int idx=-1;
	while(iterator.MoreElements()) {
		cle = iterator.GetData();

		const char* tmpZone = database.GetZoneName(cle->zone());
		if (
	(cle->Online() >= CLE_Status_Zoning) &&
	(!cle->GetGM() || cle->Anon() != 1 || admin >= cle->Admin()) &&
	(whom == 0 || (
		((cle->Admin() >= 80 && cle->GetGM()) || whom->gmlookup == 0xFFFF) &&
		(whom->lvllow == 0xFFFF || (cle->level() >= whom->lvllow && cle->level() <= whom->lvlhigh && (cle->Anon()==0 || admin>cle->Admin()))) &&
		(whom->wclass == 0xFFFF || (cle->class_() == whom->wclass && (cle->Anon()==0 || admin>cle->Admin()))) &&
		(whom->wrace == 0xFFFF || (cle->race() == whom->wrace && (cle->Anon()==0 || admin>cle->Admin()))) &&
		(whomlen == 0 || (
			(tmpZone != 0 && strncasecmp(tmpZone, whom->whom, whomlen) == 0) ||
			strncasecmp(cle->name(),whom->whom, whomlen) == 0 ||
			(strncasecmp(guild_mgr.GetGuildName(cle->GuildID()), whom->whom, whomlen) == 0) ||
			(admin >= 100 && strncasecmp(cle->AccountName(), whom->whom, whomlen) == 0)
		))
	))
) {
			line[0] = 0;
			uint32 rankstring=0xFFFFFFFF;
				if((cle->Anon()==1 && cle->GetGM() && cle->Admin()>admin) || (idx>=20 && admin<100)){ //hide gms that are anon from lesser gms and normal players, cut off at 20
					rankstring=0;
					iterator.Advance();
					continue;
				} else if (cle->GetGM()) {
					if (cle->Admin() >=250)
						rankstring=5021;
					else if (cle->Admin() >= 200)
						rankstring=5020;
					else if (cle->Admin() >= 180)
						rankstring=5019;
					else if (cle->Admin() >= 170)
						rankstring=5018;
					else if (cle->Admin() >= 160)
						rankstring=5017;
					else if (cle->Admin() >= 150)
						rankstring=5016;
					else if (cle->Admin() >= 100)
						rankstring=5015;
					else if (cle->Admin() >= 95)
						rankstring=5014;
					else if (cle->Admin() >= 90)
						rankstring=5013;
					else if (cle->Admin() >= 85)
						rankstring=5012;
					else if (cle->Admin() >= 81)
						rankstring=5011;
					else if (cle->Admin() >= 80)
						rankstring=5010;
					else if (cle->Admin() >= 50)
						rankstring=5009;
					else if (cle->Admin() >= 20)
						rankstring=5008;
					else if (cle->Admin() >= 10)
						rankstring=5007;
				}
			idx++;
			char guildbuffer[67]={0};
			if (cle->GuildID() != GUILD_NONE && cle->GuildID()>0)
				sprintf(guildbuffer,"<%s>", guild_mgr.GetGuildName(cle->GuildID()));
			uint32 formatstring=5025;
			if(cle->Anon()==1 && (admin<cle->Admin() || admin==0))
				formatstring=5024;
			else if(cle->Anon()==1 && admin>=cle->Admin() && admin>0)
				formatstring=5022;
			else if(cle->Anon()==2 && (admin<cle->Admin() || admin==0))
				formatstring=5023;//display guild
			else if(cle->Anon()==2 && admin>=cle->Admin() && admin>0)
				formatstring=5022;//display everything

	//war* wars2 = (war*)pack2->pBuffer;

	uint32 plclass_=0;
	uint32 pllevel=0;
	uint32 pidstring=0xFFFFFFFF;//5003;
	uint32 plrace=0;
	uint32 zonestring=0xFFFFFFFF;
	uint32 plzone=0;
	uint32 unknown80[2];
	if(cle->Anon()==0 || (admin>=cle->Admin() && admin>0)){
		plclass_=cle->class_();
		pllevel=cle->level();
		if(admin>=100)
			pidstring=5003;
		plrace=cle->race();
		zonestring=5006;
		plzone=cle->zone();
	}


	if(admin>=cle->Admin() && admin>0)
		unknown80[0]=cle->Admin();
	else
		unknown80[0]=0xFFFFFFFF;
	unknown80[1]=0xFFFFFFFF;//1035


	//char plstatus[20]={0};
	//sprintf(plstatus, "Status %i",cle->Admin());
	char plname[64]={0};
	strcpy(plname,cle->name());

	char placcount[30]={0};
	if(admin>=cle->Admin() && admin>0)
		strcpy(placcount,cle->AccountName());

	memcpy(bufptr,&formatstring, sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&pidstring, sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&plname, strlen(plname)+1);
	bufptr+=strlen(plname)+1;
	memcpy(bufptr,&rankstring, sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&guildbuffer, strlen(guildbuffer)+1);
	bufptr+=strlen(guildbuffer)+1;
	memcpy(bufptr,&unknown80[0], sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&unknown80[1], sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&zonestring, sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&plzone, sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&plclass_, sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&pllevel, sizeof(uint32));
	bufptr+=sizeof(uint32);
	memcpy(bufptr,&plrace, sizeof(uint32));
	bufptr+=sizeof(uint32);
	uint32 ending=0;
	memcpy(bufptr,&placcount, strlen(placcount)+1);
	bufptr+=strlen(placcount)+1;
	ending=207;
	memcpy(bufptr,&ending, sizeof(uint32));
	bufptr+=sizeof(uint32);
		}
		iterator.Advance();
	}
	pack2->Deflate();
	//zoneserver_list.SendPacket(pack2); // NO NO NO WHY WOULD YOU SEND IT TO EVERY ZONE SERVER?!?
	SendPacket(to,pack2);
	safe_delete(pack2);
	safe_delete_array(output);
	}
	catch(...){
		Log.Out(Logs::Detail, Logs::World_Server,"Unknown error in world's SendWhoAll (probably mem error), ignoring...");
		return;
	}
}
コード例 #30
0
ファイル: corpse.cpp プロジェクト: RicardoCampos/Server
Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, const glm::vec4& position, std::string time_of_death, bool rezzed, bool was_at_graveyard) {
	uint32 item_count = database.GetCharacterCorpseItemCount(in_dbid);
	char *buffer = new char[sizeof(PlayerCorpse_Struct) + (item_count * sizeof(player_lootitem::ServerLootItem_Struct))];
	PlayerCorpse_Struct *pcs = (PlayerCorpse_Struct*)buffer;
	database.LoadCharacterCorpseData(in_dbid, pcs);

	/* Load Items */
	ItemList itemlist;
	ServerLootItem_Struct* tmp = 0;
	for (unsigned int i = 0; i < pcs->itemcount; i++) {
		tmp = new ServerLootItem_Struct;
		memcpy(tmp, &pcs->items[i], sizeof(player_lootitem::ServerLootItem_Struct));
		itemlist.push_back(tmp);
	}

	/* Create Corpse Entity */
	Corpse* pc = new Corpse(
		in_dbid,			   // uint32 in_dbid
		in_charid,			   // uint32 in_charid
		in_charname.c_str(),   // char* in_charname
		&itemlist,			   // ItemList* in_itemlist
		pcs->copper,		   // uint32 in_copper
		pcs->silver,		   // uint32 in_silver
		pcs->gold,			   // uint32 in_gold
		pcs->plat,			   // uint32 in_plat
		position,
		pcs->size,			   // float in_size
		pcs->gender,		   // uint8 in_gender
		pcs->race,			   // uint16 in_race
		pcs->class_,		   // uint8 in_class
		pcs->deity,			   // uint8 in_deity
		pcs->level,			   // uint8 in_level
		pcs->texture,		   // uint8 in_texture
		pcs->helmtexture,	   // uint8 in_helmtexture
		pcs->exp,			   // uint32 in_rezexp
		was_at_graveyard	   // bool wasAtGraveyard
	);

	if (pcs->locked)
		pc->Lock();

	/* Load Item Tints */
	pc->item_tint[0].color = pcs->item_tint[0].color;
	pc->item_tint[1].color = pcs->item_tint[1].color;
	pc->item_tint[2].color = pcs->item_tint[2].color;
	pc->item_tint[3].color = pcs->item_tint[3].color;
	pc->item_tint[4].color = pcs->item_tint[4].color;
	pc->item_tint[5].color = pcs->item_tint[5].color;
	pc->item_tint[6].color = pcs->item_tint[6].color;
	pc->item_tint[7].color = pcs->item_tint[7].color;
	pc->item_tint[8].color = pcs->item_tint[8].color;

	/* Load Physical Appearance */
	pc->haircolor = pcs->haircolor;
	pc->beardcolor = pcs->beardcolor;
	pc->eyecolor1 = pcs->eyecolor1;
	pc->eyecolor2 = pcs->eyecolor2;
	pc->hairstyle = pcs->hairstyle;
	pc->luclinface = pcs->face;
	pc->beard = pcs->beard;
	pc->drakkin_heritage = pcs->drakkin_heritage;
	pc->drakkin_tattoo = pcs->drakkin_tattoo;
	pc->drakkin_details = pcs->drakkin_details;
	pc->IsRezzed(rezzed);
	pc->become_npc = false;

	pc->spell_light = pc->innate_light = NOT_USED;
	pc->UpdateEquipLightValue();
	//pc->UpdateActiveLightValue();

	safe_delete_array(pcs);

	return pc;
}