Пример #1
0
void Corpse::EndLoot(Client* client, const EQApplicationPacket* app) {
	EQApplicationPacket* outapp = new EQApplicationPacket;
	outapp->SetOpcode(OP_LootComplete);
	outapp->size = 0;
	client->QueuePacket(outapp);
	safe_delete(outapp);

	this->being_looted_by = 0xFFFFFFFF;
	if (this->IsEmpty())
		Delete();
	else
		Save();
}
Пример #2
0
bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app)
{
	if (GetAccountID() == 0) {
		clog(WORLD__CLIENT_ERR,"Name approval request with no logged in account");
		return false;
	}

	snprintf(char_name, 64, "%s", (char*)app->pBuffer);
	uchar race = app->pBuffer[64];
	uchar clas = app->pBuffer[68];

	clog(WORLD__CLIENT, "Name approval request. Name=%s, race=%s, class=%s", char_name, GetRaceName(race), GetEQClassName(clas));

	EQApplicationPacket *outapp;
	outapp = new EQApplicationPacket;
	outapp->SetOpcode(OP_ApproveName);
	outapp->pBuffer = new uchar[1];
	outapp->size = 1;

	clog(WORLD__CLIENT, "common/client.cpp line 292 pass");
	bool valid = false;
	if (!database.CheckNameFilter(char_name)) {
		clog(WORLD__CLIENT, "Invalid name");
		valid = false; 
	}
	/* Name must begin with an upper-case letter. */
	else if (islower(char_name[0])) {
		clog(WORLD__CLIENT, "Must begin with uppercase");
		valid = false; 
	} 
	else if (database.ReserveName(GetAccountID(), char_name)) {
		clog(WORLD__CLIENT, "common/client.cpp line 304 pass");
		valid = true; 	
	}
	else {
		clog(WORLD__CLIENT, "common/client.cpp line 308 pass");
		valid = false; 
	}

	clog(WORLD__CLIENT, "common/client.cpp line 312 pass");
	outapp->pBuffer[0] = valid? 1 : 0;
	QueuePacket(outapp);
	safe_delete(outapp);
	clog(WORLD__CLIENT, "common/client.cpp line 316 pass");

	if (!valid)
		memset(char_name, 0, sizeof(char_name));
		clog(WORLD__CLIENT, "common/client.cpp line 320 pass");

	return true;
}
Пример #3
0
void StructStrategy::ErrorEncoder(EQApplicationPacket **in_p, EQStreamInterface *dest, bool ack_req) {
	EQApplicationPacket *p = *in_p;
	*in_p = nullptr;

	Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Error encoding opcode %s: no encoder provided. Dropping.", OpcodeManager::EmuToName(p->GetOpcode()));

	delete p;
}
Пример #4
0
void StructStrategy::ErrorEncoder(EQApplicationPacket **in_p, EQStream *dest, bool ack_req) {
	EQApplicationPacket *p = *in_p;
	*in_p = nullptr;

	_log(NET__STRUCTS, "Error encoding opcode %s: no encoder provided. Dropping.", OpcodeManager::EmuToName(p->GetOpcode()));

	delete p;
}
Пример #5
0
bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) {

	if (GetAccountID() == 0) {
		clog(WORLD__CLIENT_ERR,"Name approval request with no logged in account");
		return false;
	}

	snprintf(char_name, 64, "%s", (char*)app->pBuffer);
	uchar race = app->pBuffer[64];
	uchar clas = app->pBuffer[68];

	clog(WORLD__CLIENT,"Name approval request. Name=%s, race=%s, class=%s",char_name,GetRaceName(race),GetEQClassName(clas));

	EQApplicationPacket *outapp;
	outapp = new EQApplicationPacket;
	outapp->SetOpcode(OP_ApproveName);
	outapp->pBuffer = new uchar[1];
	outapp->size = 1;

	bool valid;
	if(!database.CheckNameFilter(char_name)) {
		valid = false;
	}
	else if(char_name[0] < 'A' && char_name[0] > 'Z') {
		//name must begin with an upper-case letter.
		valid = false;
	}
	else if (database.ReserveName(GetAccountID(), char_name)) {
		valid = true;
	}
	else {
		valid = false;
	}
	outapp->pBuffer[0] = valid? 1 : 0;
	QueuePacket(outapp);
	safe_delete(outapp);

	if(!valid) {
		memset(char_name, 0, sizeof(char_name));
	}

	return true;
}
Пример #6
0
void Client::SendGuildMOTD(bool GetGuildMOTDReply) {
	EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildMOTD, sizeof(GuildMOTD_Struct));

	// When the Client gets an OP_GuildMOTD, it compares the text to the version it has previously stored.
	// If the text in the OP_GuildMOTD packet is the same, it does nothing. If not the same, it displays
	// the new MOTD and then stores the new text.
	//
	// When the Client receives an OP_GetGuildMOTDReply, it displays the text in the packet.
	//
	// So OP_GuildMOTD should be sent on zone entry and when an Officer changes the MOTD, and OP_GetGuildMOTDReply
	// should be sent when the client issues the /getguildmotd command.
	//
	if(GetGuildMOTDReply)
		outapp->SetOpcode(OP_GetGuildMOTDReply);

	GuildMOTD_Struct *motd = (GuildMOTD_Struct *) outapp->pBuffer;
	motd->unknown0 = 0;
	strn0cpy(motd->name, m_pp.name, 64);
	
	if(IsInAGuild()) {
		if(!guild_mgr.GetGuildMOTD(GuildID(), motd->motd, motd->setby_name)) {
			motd->setby_name[0] = '\0';
			strcpy(motd->motd, "ERROR GETTING MOTD!");
		}
	} else {
		//we have to send them an empty MOTD anywyas.
		motd->motd[0] = '\0';	//just to be sure
		motd->setby_name[0] = '\0';	//just to be sure
		
	}
		
	mlog(GUILDS__OUT_PACKETS, "Sending OP_GuildMOTD of length %d", outapp->size);
	mpkt(GUILDS__OUT_PACKET_TRACE, outapp);
	
	FastQueuePacket(&outapp);
}
Пример #7
0
void Clientlist::Process() {

	EQStream *eqs;

	while((eqs = mailsf->Pop())) {

		struct in_addr  in;

		in.s_addr = eqs->GetRemoteIP();

		_log(MAIL__CLIENT, "New Client UDP Mail connection from %s:%d", inet_ntoa(in), ntohs(eqs->GetRemotePort()));

		eqs->SetOpcodeManager(&MailOpMgr);

		Client *c = new Client(eqs);

		ClientMailConnections.push_back(c);
	}

	list<Client*>::iterator Iterator;

	for(Iterator = ClientMailConnections.begin(); Iterator != ClientMailConnections.end(); Iterator++) {

		if((*Iterator)->ClientStream->CheckClosed()) {

			struct in_addr  in;

			in.s_addr = (*Iterator)->ClientStream->GetRemoteIP();

			_log(MAIL__CLIENT, "Client connection from %s:%d closed.", inet_ntoa(in),
										   ntohs((*Iterator)->ClientStream->GetRemotePort()));
			
			safe_delete((*Iterator));

			Iterator = ClientMailConnections.erase(Iterator);

			if(Iterator == ClientMailConnections.end())
				break;

			continue;
		}

		EQApplicationPacket *app = 0;

		bool KeyValid = true;

		while( KeyValid && (app = (EQApplicationPacket *)(*Iterator)->ClientStream->PopPacket())) {

			_pkt(MAIL__PACKETS, app);

			EmuOpcode opcode = app->GetOpcode();

			switch(opcode) {

				case OP_MailLogin: {

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

					char MailBox[64];

					char Key[64];

					VARSTRUCT_DECODE_STRING(MailBox, PacketBuffer);

					// Check to see if we are running with a version of world that inserts a Connection Type
					// indicator at the start of the mailkey, and skip past it if so.
					if(strlen(PacketBuffer) == 9)
						PacketBuffer++;

					VARSTRUCT_DECODE_STRING(Key, PacketBuffer);

					string MailBoxString = MailBox, CharacterName;

					// Strip off the SOE.EQ.<shortname>.
					//
					string::size_type LastPeriod = MailBoxString.find_last_of(".");

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

					_log(MAIL__TRACE, "Received login for mailbox %s with key %s", MailBox, Key);

					if(!database.VerifyMailKey(CharacterName, (*Iterator)->ClientStream->GetRemoteIP(), Key)) {

						_log(MAIL__ERROR, "Mail Key for %s does not match, closing connection.", MailBox);

						KeyValid = false;

						break;
					}

					database.FindAccount(CharacterName.c_str(), (*Iterator));

					(*Iterator)->SendMailBoxes();

					CheckForStaleConnections((*Iterator));

					break;
				}

				case OP_Mail: {
					const char *inbuf = (const char*)app->pBuffer;

					if((app->size >= 11) && !strncmp(inbuf, "getheaders", 10)) { // getheaders

						database.SendHeaders((*Iterator));

					}
					else if((app->size >= 8) && !strncmp(inbuf, "getbody", 7)) {

							string GetBodyCommand = inbuf;

							database.SendBody((*Iterator), atoi(GetBodyCommand.substr(8).c_str()));
					}
					else if((app->size >= 7) && !strncmp(inbuf, "mailto", 6)) {

							ProcessMailTo((*Iterator), inbuf);
					}
					else if((app->size >= 17) && !strncmp(inbuf, "setmessagestatus", 16)) {

						int MessageNumber;

						int Status;

						string SetMessageCommand = inbuf;

						switch(SetMessageCommand[17]) {

							case 'R': // READ
								Status = 3;
								break;

							case 'T': // TRASH
								Status = 4;
								break;

							default: // DELETE
								Status = 0;

						}
						string::size_type NumStart = SetMessageCommand.find_first_of("123456789", 18);

						while(NumStart != string::npos) {

							string::size_type NumEnd = SetMessageCommand.find_first_of(" ", NumStart);

							if(NumEnd == string::npos) {

								MessageNumber = atoi(SetMessageCommand.substr(NumStart).c_str());

								database.SetMessageStatus(MessageNumber, Status);

								break;
							}

							MessageNumber = atoi(SetMessageCommand.substr(NumStart, NumEnd-NumStart).c_str());

							database.SetMessageStatus(MessageNumber, Status);

							NumStart = SetMessageCommand.find_first_of("123456789", NumEnd);
						}
					}
					else if((app->size >= 14) && !strncmp(inbuf, "selectmailbox", 13)) {

						string SelectMailBoxCommand = inbuf;

						string::size_type NumStart = SelectMailBoxCommand.find_first_of("0123456789", 13);

						int MailBoxNumber = atoi(SelectMailBoxCommand.substr(NumStart).c_str());

						_log(MAIL__TRACE, "%s Change to mailbox %i", (*Iterator)->MailBoxName().c_str(), MailBoxNumber);

						(*Iterator)->SetMailBox(MailBoxNumber);

						_log(MAIL__TRACE, "New mailbox is %s", (*Iterator)->MailBoxName().c_str());
						
						EQApplicationPacket *outapp = new EQApplicationPacket(OP_MailboxChange, 2);

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

						VARSTRUCT_ENCODE_INTSTRING(buf, MailBoxNumber);
						
						_pkt(MAIL__PACKETS, outapp);

						(*Iterator)->QueuePacket(outapp);

						safe_delete(outapp);
					}
					else if((app->size >= 18) && !strncmp(inbuf, "setmailforwarding", 17)) {
						// This is sent to turn mail forwarding to your Station email account on/off
						// Not implemented.
						_log(MAIL__TRACE, "Unimplemented command: %s", inbuf);
					}
					else
						_log(MAIL__ERROR, "Unhandled OP_Mail command: %s", inbuf);

					break;
				}

				default: {
					_log(MAIL__ERROR, "Unhandled mail opcode %8X", opcode);
					break;
				}
			}
			safe_delete(app);

		}
		if(!KeyValid) {
			(*Iterator)->ClientStream->Close();

			safe_delete((*Iterator));

			Iterator = ClientMailConnections.erase(Iterator);

			if(Iterator == ClientMailConnections.end())
				break;
		}

	}

}
Пример #8
0
bool Client::Process()
{
	EQApplicationPacket *app = connection->PopPacket();
	while(app)
	{
		if(server.options.IsTraceOn())
		{
			server_log->Log(log_network, "Application packet recieved from client (size %u)", app->Size());
		}

		if(server.options.IsDumpInPacketsOn())
		{
			DumpPacket(app);
		}

		switch(app->GetOpcode())
		{
		case OP_SessionReady:
			{
				if(server.options.IsTraceOn())
				{
					server_log->Log(log_network, "Session ready recieved from client.");
				}
				Handle_SessionReady((const char*)app->pBuffer, app->Size());
				break;
			}
		case OP_Login:
			{
				if(app->Size() < 20)
				{
					server_log->Log(log_network_error, "Login recieved but it is too small, discarding.");
					break;
				}

				if(server.options.IsTraceOn())
				{
					server_log->Log(log_network, "Login recieved from client.");
				}

				Handle_Login((const char*)app->pBuffer, app->Size());
				break;
			}
		case OP_ServerListRequest:
			{
				if(server.options.IsTraceOn())
				{
					server_log->Log(log_network, "Server list request recieved from client.");
				}

				SendServerListPacket();
				break;
			}
		case OP_PlayEverquestRequest:
			{
				if(app->Size() < sizeof(PlayEverquestRequest_Struct))
				{
					server_log->Log(log_network_error, "Play recieved but it is too small, discarding.");
					break;
				}

				Handle_Play((const char*)app->pBuffer);
				break;
			}
		default:
			{
				char dump[64];
				app->build_header_dump(dump);
				server_log->Log(log_network_error, "Recieved unhandled application packet from the client: %s.", dump);
			}
		}

		delete app;
		app = connection->PopPacket();
	}

	return true;
}
Пример #9
0
void Client::SendAlternateAdvancementRank(int aa_id, int level) {
	if(!zone)
		return;

	auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(aa_id, level);
	auto ability = ability_rank.first;
	auto rank = ability_rank.second;

	if(!ability) {
		return;
	}

	if(!(ability->classes & (1 << GetClass()))) {
		return;
	}

	if(!CanUseAlternateAdvancementRank(rank)) {
		return;
	}

	int size = sizeof(AARankInfo_Struct) + (sizeof(AARankEffect_Struct) * rank->effects.size()) + (sizeof(AARankPrereq_Struct) * rank->prereqs.size());
	EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendAATable, size);
	AARankInfo_Struct *aai = (AARankInfo_Struct*)outapp->pBuffer;

	aai->id = rank->id;
	aai->upper_hotkey_sid = rank->upper_hotkey_sid;
	aai->lower_hotkey_sid = rank->lower_hotkey_sid;
	aai->title_sid = rank->title_sid;
	aai->desc_sid = rank->desc_sid;
	aai->cost = rank->cost;
	aai->seq = aa_id;
	aai->type = ability->type;
	aai->spell = rank->spell;
	aai->spell_type = rank->spell_type;
	aai->spell_refresh = rank->recast_time;
	aai->classes = ability->classes;
	aai->level_req = rank->level_req;
	aai->current_level = level;
	aai->max_level = ability->GetMaxLevel(this);
	aai->prev_id = rank->prev_id;

	if(rank->next && !CanUseAlternateAdvancementRank(rank->next) || ability->charges > 0) {
		aai->next_id = -1;
	} else {
		aai->next_id = rank->next_id;
	}
	aai->total_cost = rank->total_cost;
	aai->expansion = rank->expansion;
	aai->category = ability->category;
	aai->charges = ability->charges;
	aai->grant_only = ability->grant_only;
	aai->total_effects = rank->effects.size();
	aai->total_prereqs = rank->prereqs.size();

	outapp->SetWritePosition(sizeof(AARankInfo_Struct));
	for(auto &effect : rank->effects) {
		outapp->WriteSInt32(effect.effect_id);
		outapp->WriteSInt32(effect.base1);
		outapp->WriteSInt32(effect.base2);
		outapp->WriteSInt32(effect.slot);
	}

	for(auto &prereq : rank->prereqs) {
		outapp->WriteSInt32(prereq.first);
		outapp->WriteSInt32(prereq.second);
	}

	QueuePacket(outapp);
	safe_delete(outapp);
}