Пример #1
0
void WorldSession::SendChatPacket(WorldPacket * data, uint32 langpos, int32 lang, WorldSession * originator)
{
#ifndef USING_BIG_ENDIAN
	if(lang == -1)
		*(uint32*)&data->contents()[langpos] = lang;
	else
	{
		if(CanUseCommand('c') || (originator && originator->CanUseCommand('c')))
			*(uint32*)&data->contents()[langpos] = LANG_UNIVERSAL;
		else
			*(uint32*)&data->contents()[langpos] = lang;
	}
#else
	if(lang == -1)
		*(uint32*)&data->contents()[langpos] = swap32(lang);
	else
	{
		if(CanUseCommand('c') || (originator && originator->CanUseCommand('c')))
			*(uint32*)&data->contents()[langpos] = swap32(uint32(LANG_UNIVERSAL));
		else
			*(uint32*)&data->contents()[langpos] = swap32(lang);
	}
#endif

	SendPacket(data);
}
Пример #2
0
void WorldSession::HandleBeginTrade(WorldPacket & recv_data)
{
	if(!_player->IsInWorld()) 
	{ 
		return;
	}
#ifdef FORCED_GM_TRAINEE_MODE
	if( CanUseCommand('k') && !HasGMPermissions() )
	{
		GetPlayer()->BroadcastMessage( "You are not allowed to use this feature" );
		return;
	}
#endif
	if( sWorld.getIntRate( INTRATE_DISABLE_TRADE_FEATURE ) )
	{
		GetPlayer()->BroadcastMessage( "Trade feature is disabled right now" );
		return;
	}
	sLog.outDebug( "WORLD: got CMSG_BEGIN_TRADE from player %s.", _player->GetName() );
	packetSMSG_TRADE_STATUS data;
	memset( &data, 0, sizeof( data ) );
	data.trade_status = TRADE_STATUS_INITIATED;
	data.trade_id = TRADE_ID_CONST;	//this the constant used in status update also !

	Player * plr = _player->GetTradeTarget();
	if(_player->mTradeTarget == 0 || plr == 0)
	{
		data.trade_status = TRADE_STATUS_PLAYER_NOT_FOUND;
		OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data);
		return;
	}
	// We're too far from target now?
	Player * plr2 = objmgr.GetPlayer(_player->mTradeTarget);
	if( plr2 == NULL )
	{
		return; //wtf ? player is inside the map and not in objectmanager ?
	}
	if( _player->CalcDistance( plr2 ) > 10.0f )
		data.trade_status = TRADE_STATUS_TOO_FAR_AWAY;

	//send to ourself
	OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data);
	//send to our target
	plr->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data);

	plr->mTradeStatus = data.trade_status;
	_player->mTradeStatus = data.trade_status;

//	_player->SendTradeUpdate( 0 );
//	plr->SendTradeUpdate( 0 );
}
Пример #3
0
void WorldSession::SendChatPacket(WorldPacket * data, uint32 langpos, int32 lang, WorldSession * originator)
{
	if(lang == -1)
		*(uint32*)&data->contents()[langpos] = lang;
	else
	{
		if(CanUseCommand('c') || (originator && originator->CanUseCommand('c')))
			*(uint32*)&data->contents()[langpos] = LANG_UNIVERSAL;
		else
			*(uint32*)&data->contents()[langpos] = lang;
	}

	SendPacket(data);
}
Пример #4
0
void WorldSession::HandleSetTradeGold(WorldPacket & recv_data)
{
#ifdef FORCED_GM_TRAINEE_MODE
	if( CanUseCommand('k') && !HasGMPermissions() )
	{
		GetPlayer()->BroadcastMessage( "You are not allowed to use this feature" );
		return;
	}
#endif
	if(_player->mTradeTarget == 0)
	{ 
		return;
	}
  // cebernic: TradeGold sameway.
	Player * plr = _player->GetTradeTarget();
	if(!plr) 
	{ 
		return;
	}

//	packetSMSG_TRADE_STATUS data;
//	memset( &data, 0, sizeof( data ) );
//	data.trade_status = TRADE_STATUS_STATE_CHANGED;
//	OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data);
//	plr->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data);

	plr->mTradeStatus = TRADE_STATUS_STATE_CHANGED;
	_player->mTradeStatus = TRADE_STATUS_STATE_CHANGED;


	uint64 Gold;
	recv_data >> Gold;

	if(_player->mTradeGold != Gold)
	{
		_player->mTradeGold = (Gold > _player->GetGold() ? _player->GetGold() : Gold);
		_player->SendTradeUpdate( );
	}
}
Пример #5
0
void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
{
	CHECK_PACKET_SIZE(recv_data, 9);
	WorldPacket *data;
	if(!_player->IsInWorld())
		return;

	uint32 type;
	int32 lang;

	const char * pMisc = 0;
	const char * pMsg = 0;
	recv_data >> type;
	recv_data >> lang;

	if( lang >= NUM_LANGUAGES )
		return;

	if(GetPlayer()->IsBanned())
	{
		GetPlayer()->BroadcastMessage("You cannot do that when banned.");
		return;
	}

	if(lang != -1 && !GetPermissionCount() && sWorld.flood_lines)
	{
		/* flood detection, wheeee! */
		if(UNIXTIME >= floodTime)
		{
			floodLines = 0;
			floodTime = UNIXTIME + sWorld.flood_seconds;
		}

		if((++floodLines) > sWorld.flood_lines)
		{
			if(sWorld.flood_message)
				_player->BroadcastMessage("Your message has triggered serverside flood protection. You can speak again in %u seconds.", floodTime - UNIXTIME);

			return;
		}
	}

	std::stringstream irctext;
	irctext.rdbuf()->str("");
	std::string msg;
	msg.reserve(256);

	//arghhh STFU. I'm not giving you gold or items NOOB
	switch(type)
	{
	case CHAT_MSG_EMOTE:
	case CHAT_MSG_SAY:
	case CHAT_MSG_YELL:
	case CHAT_MSG_WHISPER:
	case CHAT_MSG_CHANNEL:
		{
			if( m_muted && m_muted >= (uint32)UNIXTIME )
			{
				SystemMessage("Your voice is currently muted by a moderator.");
				return;
			}
		}break;
	}

	switch(type)
	{
	case CHAT_MSG_EMOTE:
		{
			recv_data >> msg;

			if(GetPlayer()->m_modlanguage >=0)
				data = sChatHandler.FillMessageData( CHAT_MSG_EMOTE, GetPlayer()->m_modlanguage,  msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 );
			else	
				data = sChatHandler.FillMessageData( CHAT_MSG_EMOTE, CanUseCommand('c') ? LANG_UNIVERSAL : lang,  msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 );
			GetPlayer()->SendMessageToSet( data, true ,true );

			//sLog.outString("[emote] %s: %s", _player->GetName(), msg.c_str());
			delete data;
			
			pMsg=msg.c_str();
			pMisc=0;

		}break;
	case CHAT_MSG_SAY:
		{
			recv_data >> msg;

			if (sChatHandler.ParseCommands(msg.c_str(), this) > 0)
				break;

			if(g_chatFilter->Parse(msg) == true)
			{
				SystemMessage("Your chat message was blocked by a server-side filter.");
				return;
			}

			if(GetPlayer()->m_modlanguage >=0)
			{
				data = sChatHandler.FillMessageData( CHAT_MSG_SAY, GetPlayer()->m_modlanguage,  msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 );
				GetPlayer()->SendMessageToSet( data, true );
			}
			else
			{
				if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false)
					return;

				if(lang==0 && !CanUseCommand('c'))
					return;

				data = sChatHandler.FillMessageData( CHAT_MSG_SAY, lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 );
				SendChatPacket(data, 1, lang, this);
				for(set<Player*>::iterator itr = _player->m_inRangePlayers.begin(); itr != _player->m_inRangePlayers.end(); ++itr)
				{
					(*itr)->GetSession()->SendChatPacket(data, 1, lang, this);
				}
			}

			
			//sLog.outString("[say] %s: %s", _player->GetName(), msg.c_str());
			delete data;
			pMsg=msg.c_str();
			pMisc=0;
		} break;
	case CHAT_MSG_PARTY:
	case CHAT_MSG_RAID:
	case CHAT_MSG_RAID_LEADER:
	case CHAT_MSG_RAID_WARNING:
		{
			recv_data >> msg;

			if (sChatHandler.ParseCommands(msg.c_str(), this) > 0)
				break;
			
			if(g_chatFilter->Parse(msg) == true)
			{
				SystemMessage("Your chat message was blocked by a server-side filter.");
				return;
			}

			Group *pGroup = _player->GetGroup();
			if(pGroup == NULL) break;
			
			if(GetPlayer()->m_modlanguage >=0)
				data=sChatHandler.FillMessageData( type, GetPlayer()->m_modlanguage,  msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 );
			else
				data=sChatHandler.FillMessageData( type, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0);
			if(type == CHAT_MSG_PARTY && pGroup->GetGroupType() == GROUP_TYPE_RAID)
			{
				// only send to that subgroup
				SubGroup * sgr = _player->GetGroup() ?
					_player->GetGroup()->GetSubGroup(_player->GetSubGroup()) : 0;

				if(sgr)
				{
					_player->GetGroup()->Lock();
					for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr)
					{
						if((*itr)->m_loggedInPlayer)
							(*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this);
					}
					_player->GetGroup()->Unlock();
				}
			}
			else
			{
				SubGroup * sgr;
				for(uint32 i = 0; i < _player->GetGroup()->GetSubGroupCount(); ++i)
				{
					sgr = _player->GetGroup()->GetSubGroup(i);
					_player->GetGroup()->Lock();
					for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr)
					{
						if((*itr)->m_loggedInPlayer)
							(*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this);
					}
					_player->GetGroup()->Unlock();
				}
			}
			//sLog.outString("[party] %s: %s", _player->GetName(), msg.c_str());
			delete data;
			pMsg=msg.c_str();
			pMisc=0;
		} break;
	case CHAT_MSG_GUILD:
		{
			recv_data >> msg;
			if (sChatHandler.ParseCommands(msg.c_str(), this) > 0)
			{
				break;
			}

			if(g_chatFilter->Parse(msg) == true)
			{
				SystemMessage("Your chat message was blocked by a server-side filter.");
				return;
			}

			if(_player->m_playerInfo->guild)
				_player->m_playerInfo->guild->GuildChat(msg.c_str(), this, lang);

			pMsg=msg.c_str();
			pMisc=0;
		} break;
	case CHAT_MSG_OFFICER:
		{
			recv_data >> msg;

			if (sChatHandler.ParseCommands(msg.c_str(), this) > 0)
				break;

			if(g_chatFilter->Parse(msg) == true)
			{
				SystemMessage("Your chat message was blocked by a server-side filter.");
				return;
			}

			if(_player->m_playerInfo->guild)
				_player->m_playerInfo->guild->OfficerChat(msg.c_str(), this, lang);

			pMsg=msg.c_str();
			pMisc=0;
		} break;
	case CHAT_MSG_YELL:
		{
			recv_data >> msg;

			if (sChatHandler.ParseCommands(msg.c_str(), this) > 0)
				break;

			if(g_chatFilter->Parse(msg) == true)
			{
				SystemMessage("Your chat message was blocked by a server-side filter.");
				return;
			}
			if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false)
				return;

			if(lang==0 && !CanUseCommand('c'))
				return;

			if(GetPlayer()->m_modlanguage >=0)
				data = sChatHandler.FillMessageData( CHAT_MSG_YELL, GetPlayer()->m_modlanguage,  msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 );
			else
				data = sChatHandler.FillMessageData( CHAT_MSG_YELL, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang,  msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 );

			//SendPacket(data);
			//sWorld.SendZoneMessage(data, GetPlayer()->GetZoneId(), this);
			_player->GetMapMgr()->SendChatMessageToCellPlayers(_player, data, 2, 1, lang, this);
			delete data;
			//sLog.outString("[yell] %s: %s", _player->GetName(), msg.c_str());
			pMsg=msg.c_str();
			pMisc=0;
		} break;
	case CHAT_MSG_WHISPER:
		{
			std::string to = "",tmp;
			recv_data >> to >> msg;

			if(g_chatFilter->Parse(msg) == true)
			{
				SystemMessage("Your chat message was blocked by a server-side filter.");
				return;
			}
		 
			Player *player = objmgr.GetPlayer(to.c_str(), false);
			if(!player)
			{
				data = new WorldPacket(SMSG_CHAT_PLAYER_NOT_FOUND, to.length() + 1);
				*data << to;
				SendPacket(data);
				delete data;
				break;
			}

			// Check that the player isn't a gm with his status on
			if(!_player->GetSession()->GetPermissionCount() && player->bGMTagOn && player->gmTargets.count(_player) == 0)
			{
				// Send CHAT_MSG_WHISPER_INFORM packet
				WorldPacket *data2;
				data2 = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL,msg.c_str(), player->GetGUID(), 0);
				SendPacket(data2);
				delete data2; 
				// Build automated reply
				string Reply = "This Game Master does not currently have an open ticket from you and did not receive your whisper. Please submit a new GM Ticket request if you need to speak to a GM. This is an automatic message.";
				data = sChatHandler.FillMessageData( CHAT_MSG_WHISPER, LANG_UNIVERSAL, Reply.c_str(), player->GetGUID(), 4);
				SendPacket(data);
				delete data;
				break;
			}

			if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false)
				return;

			if(lang==0 && !CanUseCommand('c'))
				return;

			if( player->Social_IsIgnoring( _player->GetLowGUID() ) )
			{
				data = sChatHandler.FillMessageData( CHAT_MSG_IGNORED, LANG_UNIVERSAL,  msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 );
				SendPacket(data);
				delete data;
			}
			else
			{
				if(GetPlayer()->m_modlanguage >=0)
					data = sChatHandler.FillMessageData( CHAT_MSG_WHISPER, GetPlayer()->m_modlanguage,  msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 );
				else
					data = sChatHandler.FillMessageData( CHAT_MSG_WHISPER, ((CanUseCommand('c') || player->GetSession()->CanUseCommand('c')) && lang != -1) ? LANG_UNIVERSAL : lang,  msg.c_str(), _player->GetGUID(), _player->bGMTagOn ? 4 : 0 );

				player->GetSession()->SendPacket(data);
				delete data;
			}

			//Sent the to Users id as the channel, this should be fine as it's not used for wisper
		  
			data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL,msg.c_str(), player->GetGUID(), 0  );
			SendPacket(data);
			delete data;

			if(player->HasFlag(PLAYER_FLAGS, 0x02))
			{
				// Has AFK flag, autorespond.
				data = sChatHandler.FillMessageData(CHAT_MSG_AFK, LANG_UNIVERSAL,  player->m_afk_reason.c_str(),player->GetGUID(), _player->bGMTagOn ? 4 : 0);
				SendPacket(data);
				delete data;
			}
			else if(player->HasFlag(PLAYER_FLAGS, 0x04))
			{
				// Has DND flag, autorespond.
				data = sChatHandler.FillMessageData(CHAT_MSG_DND, LANG_UNIVERSAL, player->m_afk_reason.c_str(),player->GetGUID(), _player->bGMTagOn ? 4 : 0);
				SendPacket(data);
				delete data;
			}

			//sLog.outString("[whisper] %s to %s: %s", _player->GetName(), to.c_str(), msg.c_str());
			pMsg=msg.c_str();
			pMisc=to.c_str();
		} break;
	case CHAT_MSG_CHANNEL:
		{
			std::string channel = "";
			recv_data >> channel;
			recv_data >> msg;
		 
			if(g_chatFilter->Parse(msg) == true)
			{
				SystemMessage("Your chat message was blocked by a server-side filter.");
				return;
			}

			if (sChatHandler.ParseCommands(msg.c_str(), this) > 0)
				break;

			Channel *chn = channelmgr.GetChannel(channel.c_str(),GetPlayer()); 
			if(chn) 
				chn->Say(GetPlayer(),msg.c_str(), NULL, false);

			//sLog.outString("[%s] %s: %s", channel.c_str(), _player->GetName(), msg.c_str());
			pMsg=msg.c_str();
			pMisc=channel.c_str();

		} break;
	case CHAT_MSG_AFK:
		{
			std::string reason;
			recv_data >> reason;
			GetPlayer()->SetAFKReason(reason);

			if(g_chatFilter->Parse(msg) == true)
			{
				SystemMessage("Your chat message was blocked by a server-side filter.");
				return;
			}

			/* WorldPacket *data, WorldSession* session, uint32 type, uint32 language, const char *channelName, const char *message*/
			if(GetPlayer()->HasFlag(PLAYER_FLAGS, 0x02))
			{
				GetPlayer()->RemoveFlag(PLAYER_FLAGS, 0x02);
				if(sWorld.GetKickAFKPlayerTime())
					sEventMgr.RemoveEvents(GetPlayer(),EVENT_PLAYER_SOFT_DISCONNECT);
			}
			else
			{
				GetPlayer()->SetFlag(PLAYER_FLAGS, 0x02);
				if(sWorld.GetKickAFKPlayerTime())
					sEventMgr.AddEvent(GetPlayer(),&Player::SoftDisconnect,EVENT_PLAYER_SOFT_DISCONNECT,sWorld.GetKickAFKPlayerTime(),1,0);
			}			
		} break;
	case CHAT_MSG_DND:
		{
			std::string reason;
			recv_data >> reason;
			GetPlayer()->SetAFKReason(reason);

			if(g_chatFilter->Parse(msg) == true)
			{
				SystemMessage("Your chat message was blocked by a server-side filter.");
				return;
			}

			if(GetPlayer()->HasFlag(PLAYER_FLAGS, 0x04))
				GetPlayer()->RemoveFlag(PLAYER_FLAGS, 0x04);
			else
			{
				GetPlayer()->SetFlag(PLAYER_FLAGS, 0x04);
			}		  
		} break;
	default:
		sLog.outError("CHAT: unknown msg type %u, lang: %u", type, lang);
	}

	if(pMsg)
		sHookInterface.OnChat(_player, type, lang, pMsg, pMisc);
}
Пример #6
0
void WorldSession::CharacterEnumProc(QueryResult * result)
{
	struct player_item
	{
		uint32 displayid;
		uint8 invtype;
		uint32 enchantment; // added in 2.4
	};

	player_item items[20];
	int8 slot;
	int8 containerslot;
	uint32 i;
	ItemPrototype * proto;
	QueryResult * res;
	CreatureInfo *info = NULL;
	uint8 num = 0;
	uint8 race;

	m_asyncQuery = false;

	//Erm, reset it here in case player deleted his DK.
	m_hasDeathKnight= false;

	// should be more than enough.. 200 bytes per char..
	WorldPacket data(SMSG_CHAR_ENUM, (result ? result->GetRowCount() * 200 : 1));

	// parse m_characters and build a mighty packet of
	// characters to send to the client.
	data << num;
	if( result )
	{
		uint64 guid;
		uint8 Class;
		uint32 bytes2;
		uint32 flags;
		uint32 banned;
		Field *fields;
		do
		{
			fields = result->Fetch();
			guid = fields[0].GetUInt32();
			bytes2 = fields[6].GetUInt32();
			Class = fields[3].GetUInt8();
			flags = fields[17].GetUInt32();
			race = fields[3].GetUInt8();

			if( _side < 0 )
			{
				// work out the side
				static uint8 sides[RACE_DRAENEI+1] = { 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0 };
				_side = sides[race];
			}

			/* build character enum, w0000t :p */
			data << fields[0].GetUInt64();		// guid
			data << fields[7].GetString();		// name
			data << fields[2].GetUInt8();		// race
			data << race;						// class
			data << fields[4].GetUInt8();		// gender
			data << fields[5].GetUInt32();		// PLAYER_BYTES
			data << uint8(bytes2 & 0xFF);		// facial hair
			data << fields[1].GetUInt8();		// Level
			data << fields[12].GetUInt32();		// zoneid
			data << fields[11].GetUInt32();		// Mapid
			data << fields[8].GetFloat();		// X
			data << fields[9].GetFloat();		// Y
			data << fields[10].GetFloat();		// Z
			data << fields[18].GetUInt32();		// GuildID

			if( fields[1].GetUInt8() > m_highestLevel )
				m_highestLevel = fields[1].GetUInt8();

			if( Class == CLASS_DEATHKNIGHT )
				m_hasDeathKnight = true;

			banned = fields[13].GetUInt32();
			if(banned && (banned<10 || banned > (uint32)UNIXTIME))
				data << uint32(0x01A04040);
			else
			{
				if(fields[16].GetUInt32() != 0)
					data << uint32(0x00A04342);
				else if(fields[15].GetUInt32() != 0)
					data << uint32(8704);                             // Dead (displaying as Ghost)
				else
					data << uint32(1);                                // alive
			}

			if((fields[19].GetUInt32() != 0) || CanUseCommand('z'))
				data << uint32(1);                                    // Player customization
			else
				data << uint32(0);                                    // Added in 3.0.2
			//data << fields[14].GetUInt8();                          // Rest State
			data << uint8(0);                                         // Added in 3.2

			if( Class == CLASS_WARLOCK || Class == CLASS_HUNTER )
			{
				res = CharacterDatabase.Query("SELECT entry FROM playerpets WHERE ownerguid="I64FMTD" AND ( active MOD 10 ) =1", guid);

				if(res)
				{
					info = CreatureNameStorage.LookupEntry(res->Fetch()[0].GetUInt32());
					delete res;
				}
				else
					info = NULL;
			}
			else
				info = NULL;

			if(info) // PET INFO uint32 displayid,  uint32 level,        uint32 familyid
				data << uint32(info->Male_DisplayID) << uint32(10) << uint32(info->Family);
			else
				data << uint32(0) << uint32(0) << uint32(0);

			res = CharacterDatabase.Query("SELECT containerslot, slot, entry, enchantments FROM playeritems WHERE ownerguid=%u", GUID_LOPART(guid));

			uint32 enchantid;
			EnchantEntry * enc;
			memset(items, 0, sizeof(player_item) * 20);
			if(res)
			{
				do
				{
					containerslot = res->Fetch()[0].GetInt8();
					slot = res->Fetch()[1].GetInt8();
					if( containerslot == -1 && slot < 19 && slot >= 0 )
					{
						proto = ItemPrototypeStorage.LookupEntry(res->Fetch()[2].GetUInt32());
						if(proto)
						{
							// slot0 = head, slot14 = cloak
							if(!(slot == 0 && (flags & (uint32)PLAYER_FLAG_NOHELM) != 0) && !(slot == 14 && (flags & (uint32)PLAYER_FLAG_NOCLOAK) != 0))
							{
								items[slot].displayid = proto->DisplayInfoID;
								items[slot].invtype = proto->InventoryType;
								if( slot == EQUIPMENT_SLOT_MAINHAND || slot == EQUIPMENT_SLOT_OFFHAND )
								{
									// get enchant id
									const char * enchant_field = res->Fetch()[3].GetString();
									if( sscanf( enchant_field , "%u,0,0;" , (unsigned int *)&enchantid ) == 1 && enchantid > 0 )
									{
										enc = dbcEnchant.LookupEntry( enchantid );
										if( enc != NULL )
											items[slot].enchantment = enc->visual;
									}
								}
							}
						}
					}
				} while(res->NextRow());
				delete res;
			}

			for( i = 0; i < 20; ++i )
			{
				data << items[i].displayid << items[i].invtype << items[i].enchantment;
			}

			if(GetClientBuild() > 11572)
			{
				for( i = 0; i < 3; i++)
					data << uint32(0) << uint8(0) << uint32(0);
			}

			num++;
		}
		while( result->NextRow() );
	}

	data.put<uint8>(0, num);

	//OUT_DEBUG("Character Enum", "Built in %u ms.", getMSTime() - start_time);
	SendPacket( &data );
}
Пример #7
0
void WorldSession::FullLogin(Player* plr)
{
	DEBUG_LOG("WorldSession", "Fully loading player %u", plr->GetLowGUID());
	SetPlayer(plr);
	m_MoverWoWGuid.Init(plr->GetGUID());

	// copy to movement array
	plr->movement_packet[0] = m_MoverWoWGuid.GetNewGuidMask();
	memcpy(&plr->movement_packet[1], m_MoverWoWGuid.GetNewGuid(), m_MoverWoWGuid.GetNewGuidLen());

	WorldPacket datab(MSG_SET_DUNGEON_DIFFICULTY, 20);
	datab << plr->iInstanceType;
	datab << uint32(0x01);
	datab << uint32(0x00);
	SendPacket(&datab);

	WorldPacket datac(MSG_SET_RAID_DIFFICULTY, 20);
	datac << plr->iRaidType;
	datac << uint32(0x01);
	datac << uint32(0x00);
	SendPacket(&datac);

	// Send first line of MOTD
	WorldPacket datat(SMSG_MOTD, sizeof(sWorld.GetMotd()) + 4);
	datat << uint32(0x04);
	datat << sWorld.GetMotd();
	SendPacket(&datat);

	/* world preload */
	packetSMSG_LOGIN_VERIFY_WORLD vwpck;
	vwpck.MapId = plr->GetMapId();
	vwpck.O = plr->GetOrientation();
	vwpck.X = plr->GetPositionX();
	vwpck.Y = plr->GetPositionY();
	vwpck.Z = plr->GetPositionZ();
	OutPacket( SMSG_LOGIN_VERIFY_WORLD, sizeof(packetSMSG_LOGIN_VERIFY_WORLD), &vwpck );

	//////////////////////////////////////////////////////////////////////////////////////////////////////
	// send voicechat state - active/inactive
	//
	// {SERVER} Packet: (0x03C7) UNKNOWN PacketSize = 2
	// |------------------------------------------------|----------------|
	// |00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|
	// |------------------------------------------------|----------------|
	// |02 01                                           |..              |
	// -------------------------------------------------------------------
	//
	//
	// Old packetdump is OLD. This is probably from 2.2.0 (that was the patch when it was added to wow)!
	//
	//////////////////////////////////////////////////////////////////////////////////////////////////////

	plr->UpdateAttackSpeed();

	// Make sure our name exists (for premade system)
	PlayerInfo * info = objmgr.GetPlayerInfo(plr->GetLowGUID());

	if(info == NULL)
	{
		info = new PlayerInfo;
		memset(info, 0, sizeof(PlayerInfo));
		info->cl = plr->getClass();
		info->gender = plr->getGender();
		info->guid = plr->GetLowGUID();
		info->name = strdup(plr->GetName());
		info->lastLevel = plr->getLevel();
		info->lastOnline = UNIXTIME;
		info->lastZone = plr->GetZoneId();
		info->race = plr->getRace();
		info->team = plr->GetTeam();
		objmgr.AddPlayerInfo(info);
	}
	plr->m_playerInfo = info;
	if(plr->m_playerInfo->guild)
	{
		plr->m_uint32Values[PLAYER_GUILDID] = plr->m_playerInfo->guild->GetGuildId();
		plr->m_uint32Values[PLAYER_GUILDRANK] = plr->m_playerInfo->guildRank->iId;
	}

	for(uint32 z = 0; z < NUM_ARENA_TEAM_TYPES; ++z)
	{
		if(_player->m_playerInfo->arenaTeam[z] != NULL)
		{
			_player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*7), _player->m_playerInfo->arenaTeam[z]->m_id);
			if(_player->m_playerInfo->arenaTeam[z]->m_leader == _player->GetLowGUID())
				_player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*7) + 1, 0);
			else
				_player->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*7) + 1, 1);
		}
	}

	info->m_loggedInPlayer = plr;

	// account data == UI config
	if(sWorld.m_useAccountData)
	{
		WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4);
		MD5Hash md5hash;
		data << uint32(UNIXTIME) << uint8(1) << uint32(0xEA);
		for (int i = 0; i < 8; i++)
		{
			AccountDataEntry* acct_data = GetAccountData(i);
			if(0xEA & (1 << i))
				data << uint32(acct_data->Time);
			md5hash.Initialize();
			md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz);
			md5hash.Finalize();
		}
		SendPacket(&data);
	}
	else
	{
		WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4);
		MD5Hash md5hash;
		data << uint32(UNIXTIME) << uint8(1) << uint32(0xEA);
		for (int i = 0; i < 8; i++)
		{
			if(0xEA & (1 << i))
				data << uint32(0);
			AccountDataEntry* acct_data = GetAccountData(i);
			if(acct_data)
			{
				md5hash.Initialize();
				md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz);
				md5hash.Finalize();
			}
		}
		SendPacket(&data);
	}

	// Set TIME OF LOGIN
	CharacterDatabase.Execute("UPDATE characters SET online = 1 WHERE guid = %u" , plr->GetLowGUID());

	_player->ResetTitansGrip();

	bool enter_world = true;
#ifndef CLUSTERING
	// Find our transporter and add us if we're on one.
	if(plr->m_TransporterGUID != 0)
	{
		Transporter* pTrans = objmgr.GetTransporter(GUID_LOPART(plr->m_TransporterGUID));
		if(pTrans)
		{
			if(plr->isDead())
			{
				plr->RemoteRevive();
			}

			float c_tposx = pTrans->GetPositionX() + plr->m_transportPosition->x;
			float c_tposy = pTrans->GetPositionY() + plr->m_transportPosition->y;
			float c_tposz = pTrans->GetPositionZ() + plr->m_transportPosition->z;
			if(plr->GetMapId() != pTrans->GetMapId())								// loaded wrong map
			{
				plr->SetMapId(pTrans->GetMapId());

				WorldPacket dataw(SMSG_NEW_WORLD, 20);
				dataw << pTrans->GetMapId() << c_tposx << c_tposy << c_tposz << plr->GetOrientation();
				SendPacket(&dataw);

				// shit is sent in worldport ack.
				enter_world = false;
			}

			plr->SetPosition(c_tposx, c_tposy, c_tposz, plr->GetOrientation(), false);
			plr->m_CurrentTransporter = pTrans;
			pTrans->AddPlayer(plr);
		}
	}
#endif
	if(plr->m_CurrentVehicle)
		plr->m_CurrentVehicle->RemovePassenger(plr);

	DEBUG_LOG( "WorldSession","Player %s logged in.", plr->GetName());

	if(plr->GetTeam() == 1)
		sWorld.HordePlayers++;
	else
		sWorld.AlliancePlayers++;

	if(plr->m_FirstLogin && !HasGMPermissions())
		OutPacket(SMSG_TRIGGER_CINEMATIC, 4, &plr->myRace->cinematic_id);

	DEBUG_LOG( "WorldSession","Created new player for existing players (%s)", plr->GetName() );

	// Login time, will be used for played time calc
	plr->m_playedtime[2] = uint32(UNIXTIME);

	//Issue a message telling all guild members that this player has signed on
	if(plr->IsInGuild())
	{
		Guild *pGuild = plr->m_playerInfo->guild;
		if(pGuild)
		{
			WorldPacket data(50);
			data.Initialize(SMSG_GUILD_EVENT);
			data << uint8(GUILD_EVENT_MOTD);
			data << uint8(0x01);
			if(pGuild->GetMOTD())
				data << pGuild->GetMOTD();
			else
				data << uint8(0);
			SendPacket(&data);

			pGuild->LogGuildEvent(GUILD_EVENT_HASCOMEONLINE, 1, plr->GetName());
		}
	}

	// Send online status to people having this char in friendlist (excluding GM's)
	if(!HasGMPermissions())
		_player->Social_TellFriendsOnline();

	// send friend list (for ignores)
	_player->Social_SendFriendList(7);

	// Send revision (if enabled)
#ifdef WIN32
	// _player->BroadcastMessage("Core server: ArcEmu %s r%u/%s-Windows-%s (www.github.com/ArcEmudev)", MSG_COLOR_WHITE, BUILD_TAG, BUILD_REVISION, CONFIG, ARCH, MSG_COLOR_LIGHTBLUE);
#else
	// _player->BroadcastMessage("Core server: ArcEmu %s r%u/%s-%s (www.github.com/ArcEmudev)", MSG_COLOR_WHITE, BUILD_TAG, BUILD_REVISION, PLATFORM_TEXT, ARCH, MSG_COLOR_LIGHTBLUE);
#endif
	// Bugs
	_player->BroadcastMessage("Bugs: %s%s", MSG_COLOR_LIGHTBLUE, BUG_TRACKER);

	if(sWorld.SendStatsOnJoin)
	{
		_player->BroadcastMessage("Online Players: %s%u |rPeak: %s%u|r Accepted Connections: %s%u",
			MSG_COLOR_WHITE, sWorld.GetSessionCount(), MSG_COLOR_WHITE, sWorld.PeakSessionCount, MSG_COLOR_WHITE, sWorld.mAcceptedConnections);
		_player->BroadcastMessage("Server Uptime: |r%s", sWorld.GetUptimeString().c_str());
	}

	// send to gms
	if(HasGMPermissions())
		sWorld.SendMessageToGMs(this, "%s %s (%s) is now online.", CanUseCommand('z') ? "Admin" : "GameMaster", _player->GetName(), GetAccountNameS(), GetPermissions());

	//Set current RestState
	if( plr->m_isResting) 		// We are in a resting zone, turn on Zzz
		plr->ApplyPlayerRestState(true);

	//Check if there is a time difference between lastlogoff and now
	if( plr->m_timeLogoff > 0 && plr->GetUInt32Value(UNIT_FIELD_LEVEL) < plr->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL))	// if timelogoff = 0 then it's the first login
	{
		uint32 currenttime = (uint32)UNIXTIME;
		uint32 timediff = currenttime - plr->m_timeLogoff;

		//Calculate rest bonus
		if( timediff > 0 )
			plr->AddCalculatedRestXP(timediff);
	}

	sHookInterface.OnEnterWorld2(_player);

	if(info->m_Group)
		info->m_Group->Update();

	// Retroactive: Level achievement
	if(plr->getLevel() > 10 && !GetPermissions())
	{
		// Retroactive: Level achievement
		_player->GetAchievementInterface()->HandleAchievementCriteriaLevelUp( _player->getLevel() );

		// Send achievement data!
		if( _player->GetAchievementInterface()->HasAchievements() )
		{
			WorldPacket * data = _player->GetAchievementInterface()->BuildAchievementData();
			_player->CopyAndSendDelayedPacket(data);
			delete data;
		}
	}

	if(enter_world && !_player->GetMapMgr())
		plr->AddToWorld();

	objmgr.AddPlayer(_player);
}
Пример #8
0
void WorldSession::HandleCharacterCustomization( WorldPacket & recv_data )
{
	CHECK_PACKET_SIZE(recv_data, 16);

	uint64 guid;
	recv_data >> guid;

	PlayerInfo * pInfo = objmgr.GetPlayerInfo((uint32)guid);
	if(pInfo == NULL)
		return;

	if(pInfo->acct != _accountId)
	{
		Disconnect();		// Cheater
		return;
	}

	QueryResult * result = CharacterDatabase.Query("SELECT recustomize FROM characters WHERE guid = %u AND acct = %u", (uint32)guid, _accountId);
	if(result == 0)
	{
		delete result;
		return;
	}
	uint32 recustomize = result[0].Fetch()[0].GetUInt32();
	if(recustomize == 0 && !CanUseCommand('z'))
	{
		delete result;
		return;
	}
	delete result;

	string name;
	recv_data >> name;

	if(!VerifyName(name.c_str(), name.length()))
	{
		uint8 err = CHAR_NAME_INVALID_CHARACTER;
		OutPacket(SMSG_CHAR_CUSTOMIZE, 1, &err);
		return;
	}

	if(g_characterNameFilter->Parse(name, false))
	{
		uint8 err = CHAR_NAME_RESERVED;
		OutPacket(SMSG_CHAR_CUSTOMIZE, 1, &err);
		return;
	}

	if(strcmp(pInfo->name, name.c_str()) && objmgr.GetPlayerInfoByName(name.c_str()) != 0)
	{
		uint8 err = CHAR_CREATE_NAME_IN_USE;
		OutPacket(SMSG_CHAR_CUSTOMIZE, 1, &err);
		return;
	}

	result = CharacterDatabase.Query("SELECT COUNT(*) FROM banned_names WHERE name = '%s'", CharacterDatabase.EscapeString(name).c_str());
	if(result)
	{
		if(result->Fetch()[0].GetUInt32() > 0)
		{
			// That name is banned!
			uint8 err = CHAR_CREATE_NAME_IN_USE;
			OutPacket(SMSG_CHAR_CUSTOMIZE, 1, &err); // You cannot use that name
			delete result;
			return;
		}
		delete result;
	}

	CapitalizeString(name);		// Correct capitalization

	uint8 gender,skin,face,hairStyle,hairColor,facialHair;

	recv_data >> gender >> skin >> hairColor >> hairStyle >> facialHair >> face;

	result = CharacterDatabase.Query("SELECT bytes2 FROM characters WHERE guid = '%u'", (uint32)guid);
	if(result == NULL)
		return;

	Field * f = result->Fetch();
	uint32 bytes2 = f[0].GetUInt32();

	bytes2 &= 0xFFFFFF00;		// Delete facial hair
	bytes2 |= facialHair;

	uint32 bytes = ((skin) | (face << 8) | (hairStyle << 16) | (hairColor << 24));

	pInfo->gender = gender;
	objmgr.RenamePlayerInfo(pInfo, pInfo->name, name.c_str());

	CharacterDatabase.WaitExecute("UPDATE characters SET name = '%s', gender = '%u', bytes = '%u', bytes2 = '%u', recustomize = 0 WHERE guid = '%u'", name.c_str(), gender, bytes, bytes2, (uint32)guid);

	WorldPacket data(SMSG_CHAR_CUSTOMIZE, 15+(name.size()+1));
	data << uint8(RESPONSE_SUCCESS);
	data << uint64(guid);
	data << name;
	data << uint8(gender);
	data << uint8(skin);
	data << uint8(face);
	data << uint8(hairStyle);
	data << uint8(hairColor);
	data << uint8(facialHair);
	SendPacket(&data);

	Log.Debug("CharacterHandler", "Received CMSG_CHAR_CUSTOMIZE.");
}
Пример #9
0
void WorldSession::HandleMessagechatOpcode(WorldPacket & recv_data)
{
	CHECK_INWORLD_RETURN

	CHECK_PACKET_SIZE(recv_data, 9);
	WorldPacket* data = NULL;

	uint32 type;
	int32 lang;

	const char* pMisc = NULL;
	const char* pMsg = NULL;
	recv_data >> type;
	recv_data >> lang;

	if(lang >= NUM_LANGUAGES)
		return;

	if(GetPlayer()->IsBanned())
	{
		GetPlayer()->BroadcastMessage("You cannot do that when banned.");
		return;
	}

	// Flood protection
	if(lang != -1 && !GetPermissionCount() && sWorld.flood_lines != 0)
	{
		/* flood detection, wheeee! */
		if(UNIXTIME >= floodTime)
		{
			floodLines = 0;
			floodTime = UNIXTIME + sWorld.flood_seconds;
		}

		if((++floodLines) > sWorld.flood_lines)
		{
			if(sWorld.flood_message)
				_player->BroadcastMessage("Your message has triggered serverside flood protection. You can speak again in %u seconds.", floodTime - UNIXTIME);

			return;
		}
	}

	switch(type)
	{
		case CHAT_MSG_EMOTE:
		case CHAT_MSG_SAY:
		case CHAT_MSG_YELL:
		case CHAT_MSG_WHISPER:
		case CHAT_MSG_CHANNEL:
			{
				if(m_muted && m_muted >= (uint32)UNIXTIME)
				{
					SystemMessage("Your voice is currently muted by a moderator.");
					return;
				}
			}
			break;
	}

	std::string msg, to = "", channel = "", tmp;
	msg.reserve(256);

	// Process packet
	switch(type)
	{
		case CHAT_MSG_SAY:
		case CHAT_MSG_EMOTE:
		case CHAT_MSG_PARTY:
		case CHAT_MSG_PARTY_LEADER:
		case CHAT_MSG_RAID:
		case CHAT_MSG_RAID_LEADER:
		case CHAT_MSG_RAID_WARNING:
		case CHAT_MSG_GUILD:
		case CHAT_MSG_OFFICER:
		case CHAT_MSG_YELL:
			recv_data >> msg;
			pMsg = msg.c_str();
			//g_chatFilter->ParseEscapeCodes((char*)pMsg,true);
			pMisc = 0;
			break;
		case CHAT_MSG_WHISPER:
			recv_data >> to >> msg;
			pMsg = msg.c_str();
			pMisc = to.c_str();
			break;
		case CHAT_MSG_CHANNEL:
			recv_data >> channel;
			recv_data >> msg;
			pMsg = msg.c_str();
			pMisc = channel.c_str();
			break;
		case CHAT_MSG_AFK:
		case CHAT_MSG_DND:
			break;
		case CHAT_MSG_BATTLEGROUND:
		case CHAT_MSG_BATTLEGROUND_LEADER:
			recv_data >> msg;
			pMsg = msg.c_str();
			break;
		default:
			LOG_ERROR("CHAT: unknown msg type %u, lang: %u", type, lang);
	}


	if(int(msg.find("|T")) > -1)
	{
		GetPlayer()->BroadcastMessage("Don't even THINK about doing that again");
		return;
	}

	// HookInterface OnChat event
	if(pMsg && !sHookInterface.OnChat(_player, type, lang, pMsg, pMisc))
		return;

	Channel* chn = NULL;
	// Main chat message processing
	switch(type)
	{
		case CHAT_MSG_EMOTE:
			{
				if(sWorld.interfaction_chat && lang > 0)
					lang = 0;

				if(g_chatFilter->Parse(msg))
				{
					SystemMessage("Your chat message was blocked by a server-side filter.");
					return;
				}

				if(GetPlayer()->m_modlanguage >= 0)
					data = sChatHandler.FillMessageData(CHAT_MSG_EMOTE, GetPlayer()->m_modlanguage,  msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);
				else if(lang == 0 && sWorld.interfaction_chat)
					data = sChatHandler.FillMessageData(CHAT_MSG_EMOTE, CanUseCommand('0') ? LANG_UNIVERSAL : lang,  msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);
				else
					data = sChatHandler.FillMessageData(CHAT_MSG_EMOTE, CanUseCommand('c') ? LANG_UNIVERSAL : lang,  msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);

				GetPlayer()->SendMessageToSet(data, true, ! sWorld.interfaction_chat);

				//sLog.outString("[emote] %s: %s", _player->GetName(), msg.c_str());
				delete data;

			}
			break;
		case CHAT_MSG_SAY:
			{
				if(sWorld.interfaction_chat && lang > 0)
					lang = 0;

				if(sChatHandler.ParseCommands(msg.c_str(), this) > 0)
					break;

				if(g_chatFilter->Parse(msg))
				{
					SystemMessage("Your chat message was blocked by a server-side filter.");
					return;
				}

				if(GetPlayer()->m_modlanguage >= 0)
				{
					data = sChatHandler.FillMessageData(CHAT_MSG_SAY, GetPlayer()->m_modlanguage,  msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);
					GetPlayer()->SendMessageToSet(data, true);
				}
				else
				{
					if(lang > 0 && LanguageSkills[lang] && ! _player->_HasSkillLine(LanguageSkills[lang]))
						return;

					if(lang == 0 && ! CanUseCommand('c') && ! sWorld.interfaction_chat)
						return;

					data = sChatHandler.FillMessageData(CHAT_MSG_SAY, lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);

					GetPlayer()->SendMessageToSet(data, true);
				}
				delete data;

			}
			break;
		case CHAT_MSG_PARTY:
		case CHAT_MSG_PARTY_LEADER:
		case CHAT_MSG_RAID:
		case CHAT_MSG_RAID_LEADER:
		case CHAT_MSG_RAID_WARNING:
			{
				if(sChatHandler.ParseCommands(msg.c_str(), this) > 0)
					break;

				if(sWorld.interfaction_chat && lang > 0)
					lang = 0;

				if(g_chatFilter->Parse(msg) == true)
				{
					SystemMessage("Your chat message was blocked by a server-side filter.");
					return;
				}

				Group* pGroup = _player->GetGroup();
				if(pGroup == NULL) break;

				if(GetPlayer()->m_modlanguage >= 0)
					data = sChatHandler.FillMessageData(type, GetPlayer()->m_modlanguage,  msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);
				else if(lang == 0 && sWorld.interfaction_chat)
					data = sChatHandler.FillMessageData(type, (CanUseCommand('0') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);
				else
					data = sChatHandler.FillMessageData(type, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang, msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);
				if(type == CHAT_MSG_PARTY && pGroup->GetGroupType() == GROUP_TYPE_RAID)
				{
					// only send to that subgroup
					SubGroup* sgr = _player->GetGroup() ?
					                _player->GetGroup()->GetSubGroup(_player->GetSubGroup()) : 0;

					if(sgr)
					{
						_player->GetGroup()->Lock();
						for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr)
						{
							if((*itr)->m_loggedInPlayer)
								(*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this);
						}
						_player->GetGroup()->Unlock();
					}
				}
				else
				{
					SubGroup* sgr;
					for(uint32 i = 0; i < _player->GetGroup()->GetSubGroupCount(); ++i)
					{
						sgr = _player->GetGroup()->GetSubGroup(i);
						_player->GetGroup()->Lock();
						for(GroupMembersSet::iterator itr = sgr->GetGroupMembersBegin(); itr != sgr->GetGroupMembersEnd(); ++itr)
						{
							if((*itr)->m_loggedInPlayer)
								(*itr)->m_loggedInPlayer->GetSession()->SendChatPacket(data, 1, lang, this);
						}
						_player->GetGroup()->Unlock();

					}
				}
				//sLog.outString("[party] %s: %s", _player->GetName(), msg.c_str());
				delete data;
			}
			break;
		case CHAT_MSG_GUILD:
			{
				if(sChatHandler.ParseCommands(msg.c_str(), this) > 0)
				{
					break;
				}

				if(g_chatFilter->Parse(msg) == true)
				{
					SystemMessage("Your chat message was blocked by a server-side filter.");
					return;
				}

				if(_player->m_playerInfo->guild)
					_player->m_playerInfo->guild->GuildChat(msg.c_str(), this, lang);

			}
			break;
		case CHAT_MSG_OFFICER:
			{
				if(sChatHandler.ParseCommands(msg.c_str(), this) > 0)
					break;

				if(g_chatFilter->Parse(msg) == true)
				{
					SystemMessage("Your chat message was blocked by a server-side filter.");
					return;
				}

				if(_player->m_playerInfo->guild)
					_player->m_playerInfo->guild->OfficerChat(msg.c_str(), this, lang);

			}
			break;
		case CHAT_MSG_YELL:
			{
				if(sWorld.interfaction_chat && lang > 0)
					lang = 0;

				if(sChatHandler.ParseCommands(msg.c_str(), this) > 0)
					break;

				if(g_chatFilter->Parse(msg) == true)
				{
					SystemMessage("Your chat message was blocked by a server-side filter.");
					return;
				}
				if(lang > 0 && LanguageSkills[lang] && _player->_HasSkillLine(LanguageSkills[lang]) == false)
					return;

				if(lang == 0 && sWorld.interfaction_chat)
					data = sChatHandler.FillMessageData(CHAT_MSG_YELL, (CanUseCommand('0') && lang != -1) ? LANG_UNIVERSAL : lang,  msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);

				else if(lang == 0 && !CanUseCommand('c'))
				{
					if(data != NULL)
						delete data;
					return;
				}

				else if(GetPlayer()->m_modlanguage >= 0)
					data = sChatHandler.FillMessageData(CHAT_MSG_YELL, GetPlayer()->m_modlanguage,  msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);
				else
					data = sChatHandler.FillMessageData(CHAT_MSG_YELL, (CanUseCommand('c') && lang != -1) ? LANG_UNIVERSAL : lang,  msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);

				_player->GetMapMgr()->SendChatMessageToCellPlayers(_player, data, 2, 1, lang, this);
				delete data;
			}
			break;
		case CHAT_MSG_WHISPER:
			{
				if(lang != -1)
					lang = LANG_UNIVERSAL; //All whispers are universal
				if(g_chatFilter->Parse(msg) == true)
				{
					SystemMessage("Your chat message was blocked by a server-side filter.");
					return;
				}

				PlayerCache* playercache = objmgr.GetPlayerCache(to.c_str(), false);
				if(playercache == NULL)
				{
					data = new WorldPacket(SMSG_CHAT_PLAYER_NOT_FOUND, to.length() + 1);
					*data << to;
					SendPacket(data);
					delete data;
					break;
				}

				if(_player->GetTeamInitial() != playercache->GetUInt32Value(CACHE_PLAYER_INITIALTEAM) && !sWorld.interfaction_chat && !playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) && !_player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM))
				{
					WorldPacket response(SMSG_CHAT_PLAYER_NOT_FOUND, to.length() + 1);
					response << to;
					SendPacket(&response);
					playercache->DecRef();
					break;
				}

				// Check that the player isn't a gm with his status on
				// TODO: Game Master's on retail are able to have block whispers after they close the ticket with the current packet.
				// When a Game Master is visible to your player it says "This player is unavailable for whisper" I need to figure out how this done.
				if(!HasPermissions() && playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) && playercache->CountValue64(CACHE_GM_TARGETS, _player->GetGUID()) == 0)
				{
					// Build automated reply
					string Reply = "SYSTEM: This Game Master does not currently have an open ticket from you and did not receive your whisper. Please submit a new GM Ticket request if you need to speak to a GM. This is an automatic message.";
					data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL, Reply.c_str(), playercache->GetGUID(), 4);
					SendPacket(data);
					delete data;
					playercache->DecRef();
					break;
				}

				if(playercache->CountValue64(CACHE_SOCIAL_IGNORELIST, _player->GetLowGUID()) > 0)
				{
					data = sChatHandler.FillMessageData(CHAT_MSG_IGNORED, LANG_UNIVERSAL,  msg.c_str(), playercache->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);
					SendPacket(data);
					delete data;
					playercache->DecRef();
					break;
				}
				else
				{
					data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER, lang,  msg.c_str(), _player->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);
					playercache->SendPacket(data);
				}


				//Sent the to Users id as the channel, this should be fine as it's not used for whisper
				if(lang != -1) //DO NOT SEND if its an addon message!
				{
					data = sChatHandler.FillMessageData(CHAT_MSG_WHISPER_INFORM, LANG_UNIVERSAL, msg.c_str(), playercache->GetGUID(), playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);
					SendPacket(data);
					delete data;
				}

				if(playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_AFK))
				{
					// Has AFK flag, autorespond.
					std::string reason;
					playercache->GetStringValue(CACHE_AFK_DND_REASON, reason);

					data = sChatHandler.FillMessageData(CHAT_MSG_AFK, LANG_UNIVERSAL, reason.c_str(), playercache->GetGUID(), _player->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);
					SendPacket(data);
					delete data;
				}
				else if(playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_DND))
				{
					// Has DND flag, autorespond.
					std::string reason;
					playercache->GetStringValue(CACHE_AFK_DND_REASON, reason);
					data = sChatHandler.FillMessageData(CHAT_MSG_DND, LANG_UNIVERSAL, reason.c_str(), playercache->GetGUID(), playercache->HasFlag(CACHE_PLAYER_FLAGS, PLAYER_FLAG_GM) ? 4 : 0);
					SendPacket(data);
					delete data;
				}

				playercache->DecRef();

			}
			break;
		case CHAT_MSG_CHANNEL:
			{
				if(g_chatFilter->Parse(msg) == true)
				{
					SystemMessage("Your chat message was blocked by a server-side filter.");
					return;
				}

				if(sChatHandler.ParseCommands(msg.c_str(), this) > 0)
					break;

				chn = channelmgr.GetChannel(channel.c_str(), GetPlayer());
				if(chn)
				{
					//g_chatFilter->ParseEscapeCodes((char*)pMsg, (chn->m_flags & CHANNEL_PACKET_ALLOWLINKS)>0 );
					chn->Say(GetPlayer(), msg.c_str(), NULL, false);
				}
			}
			break;
		case CHAT_MSG_AFK:
			{
				std::string reason = "";
				recv_data >> reason;

				GetPlayer()->SetAFKReason(reason);

				if(g_chatFilter->Parse(msg) == true)
				{
					SystemMessage("Your chat message was blocked by a server-side filter.");
					return;
				}

				/* WorldPacket *data, WorldSession* session, uint32 type, uint32 language, const char *channelName, const char *message*/
				if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_AFK))
				{
					GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAG_AFK);
					if(sWorld.GetKickAFKPlayerTime())
						sEventMgr.RemoveEvents(GetPlayer(), EVENT_PLAYER_SOFT_DISCONNECT);
				}
				else
				{
					GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_AFK);

					if(GetPlayer()->m_bg)
						GetPlayer()->m_bg->RemovePlayer(GetPlayer(), false);

					if(sWorld.GetKickAFKPlayerTime())
						sEventMgr.AddEvent(GetPlayer(), &Player::SoftDisconnect, EVENT_PLAYER_SOFT_DISCONNECT, sWorld.GetKickAFKPlayerTime(), 1, 0);
				}
			}
			break;
		case CHAT_MSG_DND:
			{
				std::string reason;
				recv_data >> reason;
				GetPlayer()->SetAFKReason(reason);

				if(g_chatFilter->Parse(msg) == true)
				{
					SystemMessage("Your chat message was blocked by a server-side filter.");
					return;
				}

				if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAG_DND))
					GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAG_DND);
				else
				{
					GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_DND);
				}
			}
			break;

		case CHAT_MSG_BATTLEGROUND:
		case CHAT_MSG_BATTLEGROUND_LEADER:
			{
				if(sChatHandler.ParseCommands(msg.c_str(), this) > 0)
					break;

				if(g_chatFilter->Parse(msg) == true)
				{
					SystemMessage("Your chat message was blocked by a server-side filter.");
					return;
				}
				if(_player->m_bg != NULL)
				{
					data = sChatHandler.FillMessageData(type, lang, msg.c_str(), _player->GetGUID());
					_player->m_bg->DistributePacketToTeam(data, _player->GetTeam());
					delete data;
				}
			}
			break;
	}
}
Пример #10
0
void WorldSession::FullLogin(Player * plr)
{
	Log.Debug("WorldSession", "Fully loading player %u", plr->GetLowGUID());
	SetPlayer(plr); 
	m_MoverWoWGuid.Init(plr->GetGUID());

	MapMgr *mgr = sInstanceMgr.GetInstance(static_cast< Object* >( plr ));  
	if (mgr && mgr->m_battleground)
	{
		/* Don't allow player to login into a bg that has ended or is full */
		if (mgr->m_battleground->HasEnded() == true ||
			mgr->m_battleground->HasFreeSlots(plr->GetTeamInitial(), mgr->m_battleground->GetType() == false)) {
				mgr = NULL;
		}
	}

	/* Trying to log to an instance that doesn't exists anymore? */
	if (!mgr)
	{
		if(!IS_INSTANCE(plr->m_bgEntryPointMap))
		{
			plr->m_position.x = plr->m_bgEntryPointX;
			plr->m_position.y = plr->m_bgEntryPointY;
			plr->m_position.z = plr->m_bgEntryPointZ;
			plr->m_position.o = plr->m_bgEntryPointO;
			plr->m_mapId = plr->m_bgEntryPointMap;
		}
		else
		{
			plr->m_position.x = plr->GetBindPositionX();
			plr->m_position.y = plr->GetBindPositionY();
			plr->m_position.z = plr->GetBindPositionZ();
			plr->m_position.o = 0;
			plr->m_mapId = plr->GetBindMapId();
		}
	}

	// copy to movement array
	movement_packet[0] = m_MoverWoWGuid.GetNewGuidMask();
	memcpy(&movement_packet[1], m_MoverWoWGuid.GetNewGuid(), m_MoverWoWGuid.GetNewGuidLen());

	/* world preload */
	packetSMSG_LOGIN_VERIFY_WORLD vwpck;
	vwpck.MapId = plr->GetMapId();
	vwpck.O = plr->GetOrientation();
	vwpck.X = plr->GetPositionX();
	vwpck.Y = plr->GetPositionY();
	vwpck.Z = plr->GetPositionZ();
	OutPacket( SMSG_LOGIN_VERIFY_WORLD, sizeof(packetSMSG_LOGIN_VERIFY_WORLD), &vwpck );

	// send voicechat state - active/inactive
	/*
	{SERVER} Packet: (0x03C7) UNKNOWN PacketSize = 2
	|------------------------------------------------|----------------|
	|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|
	|------------------------------------------------|----------------|
	|02 01							               |..              |
	-------------------------------------------------------------------
	*/


#ifndef USING_BIG_ENDIAN
	StackWorldPacket<20> datab(SMSG_VOICE_SYSTEM_STATUS);
#else
	WorldPacket datab(SMSG_VOICE_SYSTEM_STATUS, 20);
#endif

#ifdef VOICE_CHAT
	datab.Initialize(SMSG_VOICE_SYSTEM_STATUS);
	datab << uint8(2) << uint8(sVoiceChatHandler.CanUseVoiceChat() ? 1 : 0);
	SendPacket(&datab);
#else
	datab.Initialize(SMSG_VOICE_SYSTEM_STATUS);
	datab << uint8(2) << uint8(0);
#endif

	plr->UpdateAttackSpeed();
	/*if(plr->getLevel()>PLAYER_LEVEL_CAP_70)
		plr->SetUInt32Value(UNIT_FIELD_LEVEL,PLAYER_LEVEL_CAP_70);*/

	// enable trigger cheat by default
	// plr->TriggerpassCheat = HasGMPermissions();

	// Make sure our name exists (for premade system)
	PlayerInfo * info = objmgr.GetPlayerInfo(plr->GetLowGUID());
	if(info == 0)
	{
		info = new PlayerInfo;
		info->cl = plr->getClass();
		info->gender = plr->getGender();
		info->guid = plr->GetLowGUID();
		info->name = strdup(plr->GetName());
		info->lastLevel = plr->getLevel();
		info->lastOnline = UNIXTIME;
		info->lastZone = plr->GetZoneId();
		info->race = plr->getRace();
		info->team = plr->GetTeam();
		info->guild=NULL;
		info->guildRank=NULL;
		info->guildMember=NULL;
		info->m_Group=0;
		info->subGroup=0;
		objmgr.AddPlayerInfo(info);
	}
	plr->m_playerInfo = info;
	if(plr->m_playerInfo->guild)
	{
		plr->m_uint32Values[PLAYER_GUILDID] = plr->m_playerInfo->guild->GetGuildId();
		plr->m_uint32Values[PLAYER_GUILDRANK] = plr->m_playerInfo->guildRank->iId;
	}

	info->m_loggedInPlayer = plr;

	// account data == UI config
#ifndef USING_BIG_ENDIAN
	StackWorldPacket<128> data(SMSG_ACCOUNT_DATA_MD5);
#else
	WorldPacket data(SMSG_ACCOUNT_DATA_MD5, 128);
#endif

	MD5Hash md5hash;

	for (int i = 0; i < 8; i++)
	{
		AccountDataEntry* acct_data = GetAccountData(i);

		if (!acct_data->data)
		{
			data << uint64(0) << uint64(0);				// Nothing.
			continue;
		}
		md5hash.Initialize();
		md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz);
		md5hash.Finalize();

#ifndef USING_BIG_ENDIAN
		data.Write(md5hash.GetDigest(), MD5_DIGEST_LENGTH);
#else
		data.append(md5hash.GetDigest(), MD5_DIGEST_LENGTH);
#endif
	}
	SendPacket(&data);

	// Set TIME OF LOGIN
	CharacterDatabase.Execute("UPDATE characters SET online = 1 WHERE guid = %u" , plr->GetLowGUID());

	bool enter_world = true;
#ifndef CLUSTERING
	// Find our transporter and add us if we're on one.
	if(plr->m_TransporterGUID != 0)
	{
		Transporter * pTrans = objmgr.GetTransporter(GUID_LOPART(plr->m_TransporterGUID));
		if(pTrans)
		{
			if(plr->isDead())
			{
				plr->ResurrectPlayer();
				plr->SetUInt32Value(UNIT_FIELD_HEALTH, plr->GetUInt32Value(UNIT_FIELD_MAXHEALTH));
				plr->SetUInt32Value(UNIT_FIELD_POWER1, plr->GetUInt32Value(UNIT_FIELD_MAXPOWER1));
			}

			float c_tposx = pTrans->GetPositionX() + plr->m_TransporterX;
			float c_tposy = pTrans->GetPositionY() + plr->m_TransporterY;
			float c_tposz = pTrans->GetPositionZ() + plr->m_TransporterZ;
			if(plr->GetMapId() != pTrans->GetMapId())	   // loaded wrong map
			{
				plr->SetMapId(pTrans->GetMapId());
#ifndef USING_BIG_ENDIAN
				StackWorldPacket<20> dataw(SMSG_NEW_WORLD);
#else
				WorldPacket dataw(SMSG_NEW_WORLD, 20);
#endif
				dataw << pTrans->GetMapId() << c_tposx << c_tposy << c_tposz << plr->GetOrientation();
				SendPacket(&dataw);

				// shit is sent in worldport ack.
				enter_world = false;
			}

			plr->SetPosition(c_tposx, c_tposy, c_tposz, plr->GetOrientation(), false);
			plr->m_CurrentTransporter = pTrans;
			pTrans->AddPlayer(plr);
		}
	}
#endif
	if(HasGMPermissions())
	{	//Toggle for admin chat color. --Hemi
		if(_accountId == 1) //Hemi's chat color. Greenish..
			GetPlayer()->chatColor = "|cff96E798 ";
		else if(_accountId == 3) //Paws' chat color. Magneta.
			GetPlayer()->chatColor ="|cFFF52887 ";
		else if(CanUseCommand('z'))	//Admin chat colors
			GetPlayer()->chatColor = MSG_COLOR_LIGHTBLUE;	
		else if(CanUseCommand('a') && !CanUseCommand('z'))	//Co-Admin chat color
			GetPlayer()->chatColor = MSG_COLOR_LIGHTRED;		
	}

	Log.Debug("Login", "Player %s logged in.", plr->GetName());
	sLog.outString("[%s] has logged in.", plr->GetName());
	if(plr->GetTeam() == 1)
		sWorld.HordePlayers++;
	else
		sWorld.AlliancePlayers++;

	if(plr->m_FirstLogin && !HasGMPermissions())
	{
		uint32 racecinematic = plr->myRace->cinematic_id;
#ifdef USING_BIG_ENDIAN
		swap32(&racecinematic);
#endif
		OutPacket(SMSG_TRIGGER_CINEMATIC, 4, &racecinematic);

#ifdef _TEST_EXTENDED_FEATURES_
	const int classtext[] ={0,5,6,8,9,11,0,4,3,7,0,10};
	sWorld.SendLocalizedWorldText(true,"{65}",classtext[ (uint32)plr->getClass() ] , plr->GetName() , (plr->GetTeam() ? "{63}":"{64}") );
#endif

	}

	sLog.outDetail( "WORLD: Created new player for existing players (%s)", plr->GetName() );

	// Login time, will be used for played time calc
	plr->m_playedtime[2] = (uint32)UNIXTIME;

	//Issue a message telling all guild members that this player has signed on
	if(plr->IsInGuild())
	{
		Guild *pGuild = plr->m_playerInfo->guild;
		if(pGuild)
		{
			WorldPacket data(50);
			data.Initialize(SMSG_GUILD_EVENT);
			data << uint8(GUILD_EVENT_MOTD);
			data << uint8(0x01);
			if(pGuild->GetMOTD())
				data << pGuild->GetMOTD();
			else
				data << uint8(0);
			SendPacket(&data);

			pGuild->LogGuildEvent(GUILD_EVENT_HASCOMEONLINE, 1, plr->GetName());
		}
	}

	// Send online status to people having this char in friendlist
	_player->Social_TellFriendsOnline();
	// send friend list (for ignores)
	_player->Social_SendFriendList(7);

#ifndef GM_TICKET_MY_MASTER_COMPATIBLE
	GM_Ticket * ticket = objmgr.GetGMTicketByPlayer(_player->GetGUID());
	if(ticket != NULL)
	{
		//Send status change to gm_sync_channel
		Channel *chn = channelmgr.GetChannel(sWorld.getGmClientChannel().c_str(), _player);
		if(chn)
		{
			std::stringstream ss;
			ss << "GmTicket:" << GM_TICKET_CHAT_OPCODE_ONLINESTATE;
			ss << ":" << ticket->guid;
			ss << ":1";
			chn->Say(_player, ss.str().c_str(), NULL, true);
		}
	}
#endif

	// Send MOTD
	_player->BroadcastMessage(sWorld.GetMotd());

	// Send revision (if enabled)
#ifdef WIN32
	_player->BroadcastMessage("Powered by: %sArcEmu %s r%u/%s-Win-%s %s(Please report ALL bugs to www.ArcEmu.org/forums/)", MSG_COLOR_WHITE, BUILD_TAG,
		BUILD_REVISION, CONFIG, ARCH, MSG_COLOR_LIGHTBLUE);		
#else
	_player->BroadcastMessage("Powered by: %sArcEmu %s r%u/%s-%s %s(Please report ALL bugs to www.ArcEmu.org/forums/)", MSG_COLOR_WHITE, BUILD_TAG,
		BUILD_REVISION, PLATFORM_TEXT, ARCH, MSG_COLOR_LIGHTBLUE);
#endif

	if(sWorld.SendStatsOnJoin || HasGMPermissions() )
	{
		_player->BroadcastMessage("Online Players: %s%u |rPeak: %s%u|r Accepted Connections: %s%u",
			MSG_COLOR_WHITE, sWorld.GetSessionCount(), MSG_COLOR_WHITE, sWorld.PeakSessionCount, MSG_COLOR_WHITE, sWorld.mAcceptedConnections);
	}

	//Set current RestState
	if( plr->m_isResting) 		// We are resting at an inn , turn on Zzz
		plr->ApplyPlayerRestState(true);

	//Calculate rest bonus if there is time between lastlogoff and now
	if( plr->m_timeLogoff > 0 && plr->GetUInt32Value(UNIT_FIELD_LEVEL) < plr->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL))	// if timelogoff = 0 then it's the first login
	{
		uint32 currenttime = (uint32)UNIXTIME;
		uint32 timediff = currenttime - plr->m_timeLogoff;

		//Calculate rest bonus
		if( timediff > 0 ) 
			plr->AddCalculatedRestXP(timediff);
	}

#ifdef CLUSTERING
	plr->SetInstanceID(forced_instance_id);
	plr->SetMapId(forced_map_id);
#else
	sHookInterface.OnEnterWorld2(_player);
#endif

	if(info->m_Group)
		info->m_Group->Update();

	if(enter_world && !_player->GetMapMgr())
	{
		plr->AddToWorld();
	}

	objmgr.AddPlayer(_player);

	if(info->m_Group == NULL)
		plr->SendDungeonDifficulty();
}
void WorldSession::FullLogin(Player* plr)
{
    sLog.Debug("WorldSession", "Fully loading player %u", plr->GetLowGUID());
    SetPlayer(plr);
    m_MoverWoWGuid.Init(plr->GetGUID());

    /* world preload */
    packetSMSG_LOGIN_VERIFY_WORLD vwpck;
    vwpck.MapId = plr->GetMapId();
    vwpck.O = plr->GetOrientation();
    vwpck.X = plr->GetPositionX();
    vwpck.Y = plr->GetPositionY();
    vwpck.Z = plr->GetPositionZ();
    OutPacket( SMSG_LOGIN_VERIFY_WORLD, sizeof(packetSMSG_LOGIN_VERIFY_WORLD), &vwpck );

    // send voicechat state - active/inactive
    /*
    {SERVER} Packet: (0x03C7) UNKNOWN PacketSize = 2
    |------------------------------------------------|----------------|
    |00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|
    |------------------------------------------------|----------------|
    |02 01                                           |..              |
    -------------------------------------------------------------------
    */

    WorldPacket datab(SMSG_FEATURE_SYSTEM_STATUS, 2);
    datab << uint8(2) << uint8(0);
    SendPacket(&datab);

    datab.Initialize(SMSG_LEARNED_DANCE_MOVES, 8);
    datab << uint32(0);
    datab << uint32(0);
    SendPacket(&datab);

    plr->UpdateStats();

    // Anti max level hack.
    if(sWorld.LevelCap_Custom_All && (plr->getLevel() > sWorld.LevelCap_Custom_All))
        plr->SetUInt32Value(UNIT_FIELD_LEVEL, sWorld.LevelCap_Custom_All);

    // Enable certain GM abilities on login.
    if(HasGMPermissions())
    {
        plr->bGMTagOn = true;
        plr->m_isGmInvisible = true;
        plr->m_invisible = true;
        plr->bInvincible = true;
        if(CanUseCommand('z'))
        {
            plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_DEVELOPER);
            plr->triggerpass_cheat = true; // Enable for admins automatically.
        }
        else
            plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_GM);
    }

    // Make sure our name exists (for premade system)
    PlayerInfo * info = objmgr.GetPlayerInfo(plr->GetLowGUID());
    if(info == NULL)
    {
        info = new PlayerInfo;
        memset(info, 0, sizeof(PlayerInfo));
        info->_class = plr->getClass();
        info->gender = plr->getGender();
        info->guid = plr->GetLowGUID();
        info->name = strdup(plr->GetName());
        info->lastLevel = plr->getLevel();
        info->lastOnline = UNIXTIME;
        info->lastZone = plr->GetZoneId();
        info->race = plr->getRace();
        info->team = plr->GetTeam();
        objmgr.AddPlayerInfo(info);
    }

    plr->m_playerInfo = info;
    if(plr->m_playerInfo->GuildId)
    {
        plr->m_uint32Values[PLAYER_GUILDID] = plr->m_playerInfo->GuildId;
        plr->m_uint32Values[PLAYER_GUILDRANK] = plr->m_playerInfo->GuildRank;
    }

    for(uint32 z = 0; z < NUM_ARENA_TEAM_TYPES; ++z)
    {
        if(plr->m_playerInfo->arenaTeam[z] != NULL)
        {
            plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*6), plr->m_playerInfo->arenaTeam[z]->m_id);
            if(plr->m_playerInfo->arenaTeam[z]->m_leader == plr->GetLowGUID())
                plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*6) + 1, 0);
            else
                plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*6) + 1, 1);
        }
    }

    info->m_loggedInPlayer = plr;

    // account data == UI config
    if(sWorld.m_useAccountData)
    {
        WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4);
        MD5Hash md5hash;
        data << uint32(UNIXTIME) << uint8(1) << uint32(0xEA);
        for (int i = 0; i < 8; i++)
        {
            AccountDataEntry* acct_data = GetAccountData(i);
            if(0xEA & (1 << i))
                data << uint32(acct_data->Time);
            md5hash.Initialize();
            md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz);
            md5hash.Finalize();
        }
        SendPacket(&data);
    }
    else
    {
        WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4);
        MD5Hash md5hash;
        data << uint32(UNIXTIME) << uint8(1) << uint32(0xEA);
        for (int i = 0; i < 8; i++)
        {
            if(0xEA & (1 << i))
                data << uint32(0);
            AccountDataEntry* acct_data = GetAccountData(i);
            if(acct_data)
            {
                md5hash.Initialize();
                md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz);
                md5hash.Finalize();
            }
        }
        SendPacket(&data);
    }

    // Set TIME OF LOGIN
    CharacterDatabase.Execute("UPDATE characters SET online = 1 WHERE guid = %u" , plr->GetLowGUID());

    bool enter_world = true;

    // Find our transporter and add us if we're on one.
    if(plr->GetTransportGuid() != 0)
    {
        uint64 transGuid = plr->GetTransportGuid();
        Transporter* pTrans = objmgr.GetTransporter(GUID_LOPART(transGuid));
        if(pTrans)
        {
            if(plr->isDead())
                plr->RemoteRevive();

            float c_tposx, c_tposy, c_tposz, c_tposo;
            plr->GetMovementInfo()->GetTransportPosition(c_tposx, c_tposy, c_tposz, c_tposo);
            c_tposx += pTrans->GetPositionX();
            c_tposy += pTrans->GetPositionY();
            c_tposz += pTrans->GetPositionZ();

            if(plr->GetMapId() != pTrans->GetMapId())   // loaded wrong map
            {
                plr->SetMapId(pTrans->GetMapId());

                WorldPacket dataw(SMSG_NEW_WORLD, 20);
                dataw << pTrans->GetMapId() << c_tposx << c_tposy << c_tposz << c_tposo;
                SendPacket(&dataw);

                // shit is sent in worldport ack.
                enter_world = false;
            }

            plr->SetPosition(c_tposx, c_tposy, c_tposz, c_tposo);
            plr->m_CurrentTransporter = pTrans;
            pTrans->AddPlayer(plr);
        }
    }

    if(plr->GetVehicle())
        plr->GetVehicle()->RemovePassenger(plr);

    sLog.Debug( "WorldSession","Player %s logged in.", plr->GetName());

    if(plr->GetTeam() == 1)
        sWorld.HordePlayers++;
    else
        sWorld.AlliancePlayers++;

    if(sWorld.SendMovieOnJoin && plr->m_FirstLogin && !HasGMPermissions())
        plr->SendCinematic(plr->myRace->cinematic_id);

    sLog.Debug( "WorldSession","Created new player for existing players (%s)", plr->GetName() );

    // Login time, will be used for played time calc
    plr->m_playedtime[2] = (uint32)UNIXTIME;

    // Send online status to people having this char in friendlist
    plr->Social_TellOnlineStatus();

    // send friend list (for ignores)
    plr->Social_SendFriendList(7);

    // send to gms
    if(HasGMPermissions())
        sWorld.SendMessageToGMs(this, "%s%s %s (%s) is now online.|r", MSG_COLOR_GOLD, CanUseCommand('z') ? "Admin" : "GameMaster", plr->GetName(), GetAccountNameS(), GetPermissions());

    //Set current RestState
    if( plr->m_isResting)       // We are in a resting zone, turn on Zzz
        plr->ApplyPlayerRestState(true);

    //Check if there is a time difference between lastlogoff and now
    if( plr->m_timeLogoff > 0 && plr->GetUInt32Value(UNIT_FIELD_LEVEL) < plr->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL))   // if timelogoff = 0 then it's the first login
    {
        uint32 currenttime = (uint32)UNIXTIME;
        uint32 timediff = currenttime - plr->m_timeLogoff;

        //Calculate rest bonus
        if( timediff > 0 )
            plr->AddCalculatedRestXP(timediff);
    }

    sHookInterface.OnFullLogin(plr);

    if(info->m_Group)
        info->m_Group->Update();

    if(!sWorld.m_blockgmachievements || !HasGMPermissions())
    {
        // Retroactive: Level achievement
        plr->GetAchievementInterface()->HandleAchievementCriteriaLevelUp( plr->getLevel() );

        // Send achievement data!
        if( plr->GetAchievementInterface()->HasAchievements() )
        {
            WorldPacket * data = plr->GetAchievementInterface()->BuildAchievementData();
            plr->CopyAndSendDelayedPacket(data);
            delete data;
        }
    }

    if(enter_world && !plr->GetMapMgr())
        plr->AddToWorld(true);

    sTracker.CheckPlayerForTracker(plr, true);

    // If we have the talent, it returns anyway, so just call the function.
    plr->ResetTitansGrip();

    if(plr->GetItemInterface())
        plr->GetItemInterface()->CheckAreaItems();
    objmgr.AddPlayer(plr);
}
Пример #12
0
void WorldSession::HandleAcceptTrade(WorldPacket & recv_data) 
{
#ifdef FORCED_GM_TRAINEE_MODE
	if( CanUseCommand('k') && !HasGMPermissions() )
	{
		GetPlayer()->BroadcastMessage( "You are not allowed to use this feature" );
		return;
	}
#endif
	if( sWorld.getIntRate( INTRATE_DISABLE_TRADE_FEATURE ) )
	{
		GetPlayer()->BroadcastMessage( "Trade feature is disabled right now" );
		return;
	}
	Player * plr = _player->GetTradeTarget();
	if(_player->mTradeTarget == 0 || !plr)
	{ 
		return;
	}

	packetSMSG_TRADE_STATUS data;
	memset( &data, 0, sizeof( data ) );
	data.trade_status = TRADE_STATUS_ACCEPTED;
	OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data);
	plr->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data);
	
	_player->mTradeStatus = TRADE_STATUS_ACCEPTED;	//when both have this status we can close the deal

	bool bag_hack_detected = false;
	if(plr->mTradeStatus == TRADE_STATUS_ACCEPTED)
	{
		// Ready!
		uint32 ItemCount = 0;
		uint32 TargetItemCount = 0;
		Player * pTarget = plr;

/*		// Calculate Item Count
		for(uint32 Index = 0; Index < 7; ++Index)
		{
			if(_player->mTradeItems[Index] != 0)	++ItemCount;
			if(pTarget->mTradeItems[Index] != 0)	++TargetItemCount;
		}*/
		

		// Calculate Count
		for(uint32 Index = 0; Index < TRADE_MAX_TRADABLE_ITEMS; ++Index) // cebernic: checking for MAX_TRADE_TRADABLE_ITEMS items ,untradable item check via others func.
		{
			Item * pItem;

			// safely trade checking
			pItem = _player->mTradeItems[Index];
			if( pItem )
			{
				if( ( pItem->IsContainer() && SafeContainerCast(pItem)->HasItems() )   || ( pItem->GetProto() && pItem->GetProto()->Bonding==ITEM_BIND_ON_PICKUP) )
				{
					ItemCount = 0;
					TargetItemCount = 0;
					bag_hack_detected = true;
					break;
				}
				else ++ItemCount;
			}					
			
			pItem = pTarget->mTradeItems[Index];
			if( pItem )
			{
				if( ( pItem->IsContainer() && SafeContainerCast(pItem)->HasItems() )   || ( pItem->GetProto() && pItem->GetProto()->Bonding==ITEM_BIND_ON_PICKUP) )
				{
					ItemCount = 0;
					TargetItemCount = 0;
					bag_hack_detected = true;
					break;
				}
				else 
					++TargetItemCount;
			}					

			//if(_player->mTradeItems[Index] != 0)	++ItemCount;
			//if(pTarget->mTradeItems[Index] != 0)	++TargetItemCount;
		}

		

		if( (_player->m_ItemInterface->CalculateFreeSlots(NULL) + ItemCount) < TargetItemCount ||
			(pTarget->m_ItemInterface->CalculateFreeSlots(NULL) + TargetItemCount) < ItemCount ||
			bag_hack_detected == true ||
			(ItemCount==0 && TargetItemCount==0 && !pTarget->mTradeGold && !_player->mTradeGold) )	// ceberwow added it
		{
			// Not enough slots on one end.
			data.trade_status = TRADE_STATUS_CANCELLED;
		}
		else
		{
			data.trade_status = TRADE_STATUS_COMPLETE;
			uint64 Guid;
			Item * pItem;
			
			// Remove all items from the players inventory
			for(uint32 Index = 0; Index < TRADE_MAX_TRADABLE_ITEMS; ++Index)
			{
				Guid = _player->mTradeItems[Index] ? _player->mTradeItems[Index]->GetGUID() : 0;
				if(Guid != 0)
				{
					if( _player->mTradeItems[Index]->GetProto()->Bonding == ITEM_BIND_ON_PICKUP ||
						_player->mTradeItems[Index]->GetProto()->Bonding  >=  ITEM_BIND_QUEST  )
					{
						_player->mTradeItems[Index] = NULL;
					}
					else
					{
						if(GetPermissionCount()>0)
							sGMLog.writefromsession(this, "traded item %s to %s", _player->mTradeItems[Index]->GetProto()->Name1, pTarget->GetName());
						pItem = _player->m_ItemInterface->SafeRemoveAndRetreiveItemByGuid(Guid, true);
					}
				}

				Guid = pTarget->mTradeItems[Index] ? pTarget->mTradeItems[Index]->GetGUID() : 0;
				if(Guid != 0)
				{
					if( pTarget->mTradeItems[Index]->GetProto()->Bonding == ITEM_BIND_ON_PICKUP ||  
						pTarget->mTradeItems[Index]->GetProto()->Bonding  >=  ITEM_BIND_QUEST )
					{
						pTarget->mTradeItems[Index] = NULL;
					}
					else
					{
						if(pTarget->GetSession() && pTarget->GetSession()->GetPermissionCount()>0)
							sGMLog.writefromsession(pTarget->GetSession(), "traded item %s to %s", pTarget->mTradeItems[Index]->GetProto()->Name1, _player->GetName());
						pTarget->m_ItemInterface->SafeRemoveAndRetreiveItemByGuid(Guid, true);
					}
				}
			}

			// Dump all items back into the opposite players inventory
			for(uint32 Index = 0; Index < TRADE_MAX_TRADABLE_ITEMS; ++Index)
			{
				pItem = _player->mTradeItems[Index];
				if(pItem != 0 && pTarget)
				{
					pItem->SetOwner(pTarget); // crash fixed.
					if( !pTarget->m_ItemInterface->AddItemToFreeSlot(&pItem) )
					{
						pItem->DeleteMe();
						pItem = NULL;
						_player->mTradeItems[Index] = NULL;
						continue;
					}
				}

				pItem = pTarget->mTradeItems[Index];
				if(pItem != 0 && _player)
				{
					pItem->SetOwner(_player);
					if( !_player->m_ItemInterface->AddItemToFreeSlot(&pItem) )
					{
						pItem->DeleteMe();
						pItem = NULL;
						pTarget->mTradeItems[Index] = NULL;
						continue;
					}
				}
			}

			// Trade Gold
			if(pTarget->mTradeGold && pTarget->GetGold() >= pTarget->mTradeGold )
			{
				_player->ModGold(pTarget->mTradeGold);
				pTarget->ModGold(-(int64)pTarget->mTradeGold);
				if(GetPermissionCount()>0)
					sGMLog.writefromsession(this, "traded(gave) %u gold to %s", pTarget->mTradeGold, pTarget->GetName());
			}

			if(_player->mTradeGold && _player->GetGold() >= _player->mTradeGold)
			{
				pTarget->ModGold( _player->mTradeGold);
				_player->ModGold( -(int64)_player->mTradeGold);
				if(pTarget->GetSession() && pTarget->GetSession()->GetPermissionCount()>0)
					sGMLog.writefromsession(pTarget->GetSession(), "traded(gave) %u gold to %s", _player->mTradeGold, _player->GetName());
			}

			// Close Window
			data.trade_status = TRADE_STATUS_COMPLETE;
			
		}

		OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data);
		plr->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data);

		_player->mTradeStatus = TRADE_STATUS_COMPLETE;
		plr->mTradeStatus = TRADE_STATUS_COMPLETE;

		// Reset Trade Vars
		_player->ResetTradeVariables();		
		plr->ResetTradeVariables();

		//removed by zack. Hehe, just a way to spam db with saves. Not funny
		// added alternative way as item saves before 
		// Save for eachother
		//plr->SaveToDB(false);
		//_player->SaveToDB(false);
	}
}
Пример #13
0
void WorldSession::HandleSetTradeItem(WorldPacket & recv_data)
{
#ifdef FORCED_GM_TRAINEE_MODE
	if( CanUseCommand('k') && !HasGMPermissions() )
	{
		GetPlayer()->BroadcastMessage( "You are not allowed to use this feature" );
		return;
	}
#endif
	if(_player->mTradeTarget == 0)
	{ 
		sLog.outDebug("HandleSetTradeItem: missing trade target\n");
		return;
	}

	if(!_player->IsInWorld()) 
	{ 
		sLog.outDebug("HandleSetTradeItem: not in world\n");
		return;
	}
	  
	CHECK_PACKET_SIZE(recv_data, 3);

	uint8 TradeSlot = recv_data.contents()[1];
	uint8 SourceSlot = recv_data.contents()[2];
	uint8 SourceBag = recv_data.contents()[0];
	Player * pTarget = _player->GetTradeTarget();

	Item * pItem = _player->GetItemInterface()->GetInventoryItem(SourceBag, SourceSlot);

	if( pTarget == NULL || pItem == 0 || TradeSlot >= TRADE_TOTAL_TRADE_SLOTS || ( TradeSlot < TRADE_MAX_TRADABLE_ITEMS && pItem->IsSoulbound() ) )
	{ 
		sLog.outDebug("HandleSetTradeItem: target missing or incorect item/slot. target(%u),item(%u),slot(%u))\n",pTarget != NULL,pItem != 0,TradeSlot );
 		return;
	}

	if( TradeSlot < TRADE_MAX_TRADABLE_ITEMS && pItem->IsAccountbound() )
	{
		PlayerInfo* pinfo = ObjectMgr::getSingleton().GetPlayerInfo(_player->mTradeTarget);
		if(pinfo == NULL || GetAccountId() != pinfo->acct) // can't trade account-based items
		{ 
			sLog.outDebug("HandleSetTradeItem: item is account bound\n");
			return;
		}
	}
/*	if( pItem->IsContainer() )
	{
		if(_player->GetItemInterface()->IsBagSlot(SourceSlot))
		return;*/
		
	packetSMSG_TRADE_STATUS data;
	memset( &data, 0, sizeof( data ) );
//	data.trade_status = TRADE_STATUS_STATE_CHANGED;
//	OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data);
//	pTarget->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data);

	pTarget->mTradeStatus = TRADE_STATUS_STATE_CHANGED;
	_player->mTradeStatus = TRADE_STATUS_STATE_CHANGED;


	if( pItem->IsContainer() )
	{
		if( SafeContainerCast(pItem)->HasItems() )
		{
			_player->GetItemInterface()->BuildInventoryChangeError(pItem,0, INV_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS);

			//--trade cancel
			data.trade_status = TRADE_STATUS_CANCELLED;
			OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data);
			
			Player * plr = _player->GetTradeTarget();
			if(plr)
			{
			    if(plr->m_session && plr->m_session->GetSocket())
					plr->m_session->OutPacket(SMSG_TRADE_STATUS,sizeof( packetSMSG_TRADE_STATUS ), &data);
			    plr->ResetTradeVariables();
			}

			_player->ResetTradeVariables();
			sLog.outDebug("HandleSetTradeItem: Container with items cannot be traded\n");
			return;
		}
	}			
		
	//well that covers all slots i think (MAX_TRADE_TRADABLE_ITEMS is temporal slot)
	if(TradeSlot < TRADE_MAX_TRADABLE_ITEMS)
	{
		if(pItem->IsSoulbound())
		{
			sCheatLog.writefromsession(this, "tried to cheat trade a soulbound item");
			sLog.outDebug("HandleSetTradeItem: Cannot trade soulbound item\n");
			Item *ti = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SourceBag, SourceSlot, false);
			if( ti )
			{
				ti->DeleteFromDB();
				ti->DeleteMe();
				ti = NULL;
			}
			string sReason = "Soulboundtrade 1";
			uint32 uBanTime = (uint32)UNIXTIME + 60*60; //60 minutes ban
			_player->SetBanned( uBanTime, sReason );
			sEventMgr.AddEvent( _player, &Player::_Kick, EVENT_PLAYER_KICK, 7000, 1, 0 );
			return; //item is not valid anymore !
		}
		//this was checked earlier ? How the hack did we get here again ?
		else if(pItem->IsAccountbound() && pTarget->GetSession() && pTarget->GetSession()->GetAccountId() != GetAccountId() )
		{
			PlayerInfo* pinfo = ObjectMgr::getSingleton().GetPlayerInfo(_player->mTradeTarget);
			if(pinfo == NULL || GetAccountId() != pinfo->acct) // can't trade account-based items
			{
				sLog.outDebug("HandleSetTradeItem: Cannot trade account bound item\n");
				sCheatLog.writefromsession(this, "tried to cheat trade an accountbound item");
				Item *ti = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SourceBag, SourceSlot, false);
				if( ti )
				{
					ti->DeleteFromDB();
					ti->DeleteMe();
					ti = NULL;
				}
				string sReason = "Account bound itemtrade";
				uint32 uBanTime = (uint32)UNIXTIME + 60*60; //60 minutes ban
				_player->SetBanned( uBanTime, sReason );
				sEventMgr.AddEvent( _player, &Player::_Kick, EVENT_PLAYER_KICK, 7000, 1, 0 );
				return; //item is not valid anymore !
			}
		}
	}

	for(uint32 i = 0; i < TRADE_TOTAL_TRADE_SLOTS; ++i)
	{
		// duping little shits
		if( TradeSlot != i && ( _player->mTradeItems[i] == pItem || pTarget->mTradeItems[i] == pItem ) )
		{
			sCheatLog.writefromsession(this, "tried to dupe an item through trade");
			Item *ti = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SourceBag, SourceSlot, false);
			if( ti )
			{
				ti->DeleteFromDB();
				ti->DeleteMe();
				ti = NULL;
			}
			GetPlayer()->SoftDisconnect();
			sLog.outDebug("HandleSetTradeItem: item dupe detected\n");
			return;
		}
	}

	if( SourceBag <= INVENTORY_SLOT_NOT_SET && //we are removing from our direct character slot and not from a bag
		SourceSlot >= INVENTORY_SLOT_BAG_START && SourceSlot < INVENTORY_SLOT_BAG_END)
	{
		//More duping woohoo
        Item *ti = _player->GetItemInterface()->SafeRemoveAndRetreiveItemFromSlot(SourceBag, SourceSlot, false);
		if( ti )
		{
			ti->DeleteFromDB();
			ti->DeleteMe();
			ti = NULL;
		}
		sCheatLog.writefromsession(this, "tried to cheat trade a soulbound item");
		string sReason = "trading from bagslot";
		uint32 uBanTime = (uint32)UNIXTIME + 60*60; //60 minutes ban
		_player->SetBanned( uBanTime, sReason );
		sEventMgr.AddEvent( _player, &Player::_Kick, EVENT_PLAYER_KICK, 7000, 1, 0 );
		sLog.outDebug("HandleSetTradeItem: Cannot trade from bagslot\n");
		return; //item is not valid anymore !
	}

	_player->mTradeItems[TradeSlot] = pItem;
	_player->SendTradeUpdate();
}
Пример #14
0
void WorldSession::HandleInitiateTrade(WorldPacket & recv_data)
{
	if(!_player->IsInWorld()) 
	{ 
		return;
	}
#ifdef FORCED_GM_TRAINEE_MODE
	if( CanUseCommand('k') && !HasGMPermissions() )
	{
		GetPlayer()->BroadcastMessage( "You are not allowed to use this feature" );
		return;
	}
#endif
	if( sWorld.getIntRate( INTRATE_DISABLE_TRADE_FEATURE ) )
	{
		GetPlayer()->BroadcastMessage( "Trade feature is disabled right now" );
		return;
	}
//	CHECK_PACKET_SIZE(recv_data, 8);
//	uint64 guid;
//	recv_data >> guid;
	uint8 GUID_mask;
	uint8 GUID_bytes[8];
	memset( GUID_bytes, 0, sizeof( GUID_bytes ) );

	recv_data >> GUID_mask;

	if( GUID_mask & BIT_0x01 )
		recv_data >> GUID_bytes[2];
	if( GUID_mask & BIT_0x02 )
		recv_data >> GUID_bytes[1];
	if( GUID_mask & BIT_0x40 )
		recv_data >> GUID_bytes[3];
	if( GUID_mask & BIT_0x04 )
		recv_data >> GUID_bytes[0];

	uint8 GUID_bytes_obfuscated[8];
	*(uint64*)GUID_bytes_obfuscated = *(uint64*)GUID_bytes;

	GUID_un_obfuscate( GUID_bytes );
	Player * pTarget = _player->GetMapMgr()->GetPlayer( *(uint64*)GUID_bytes );
	uint32 TradeStatus = TRADE_STATUS_PROPOSED;

	if(pTarget == 0)
	{
		TradeStatus = TRADE_STATUS_PLAYER_NOT_FOUND;
		OutPacket(SMSG_TRADE_STATUS, 4, &TradeStatus);
		return;
	}

	// Handle possible error outcomes
	if(pTarget->CalcDistance(_player) > 10.0f)		// This needs to be checked
		TradeStatus = TRADE_STATUS_TOO_FAR_AWAY;
	else if(pTarget->IsDead())
		TradeStatus = TRADE_STATUS_DEAD;
	else if(pTarget->mTradeTarget != 0)
		TradeStatus = TRADE_STATUS_ALREADY_TRADING;
	else if(pTarget->GetTeam() != _player->GetTeam() && GetPermissionCount() == 0 && !sWorld.interfaction_trade)
		TradeStatus = TRADE_STATUS_WRONG_FACTION;

	if(TradeStatus == TRADE_STATUS_PROPOSED)
	{
		_player->ResetTradeVariables();
		pTarget->ResetTradeVariables();

		pTarget->mTradeTarget = _player->GetLowGUID();
		_player->mTradeTarget = pTarget->GetLowGUID();

		pTarget->mTradeStatus = TradeStatus;
		_player->mTradeStatus = TradeStatus;
	}
/*
13329
ME
{CLIENT} Packet: (0x4106) CMSG_INITIATE_TRADE PacketSize = 8 TimeStamp = 32130418
8A A9 79 02 00 00 00 04 
to me
{SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32131338
0E 69 2B 33 18 8A A9 79 02 00 00 00 04 03 00 00 00 AB 2A 00 00 90 BC 61 58 AB 01 00 00 00 00 00 00 00 -> trade proposed
to him
{SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32209838
80 B9 46 42 98 8A A9 79 02 00 00 00 04 90 BC 61 58 AB 2A 00 00 B3 47 A5 00 00 01 00 00 00 AB 2A 00 00 -> trade proposed
him
{CLIENT} Packet: (0x4107) CMSG_BEGIN_TRADE PacketSize = 0 TimeStamp = 32209854

to me
{SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32131338
01 00 00 00 00 10 BD 46 42 00 00 00 00 88 E3 29 0E 00 00 00 00 07 01 00 00 00 02 00 00 00 AB 2A 00 00 -> trade initiated
to him
{SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32209994
00 00 00 00 AE 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 09 01 00 00 00 02 00 00 00 00 00 00 00 -> trade initiated 
to me
{SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32379442
80 B9 46 42 98 10 BD 46 42 00 00 00 00 00 00 00 00 AA 2A 00 00 10 0A 6C 58 AB 08 00 00 00 00 00 00 00 ->trade complete
to him
{SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32456725
05 00 00 00 0A 20 B8 46 42 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 04 00 00 00 00 00 00 00 ->trade accepted
to him
{SERVER} Packet: (0x2830) SMSG_TRADE_STATUS PacketSize = 34 TimeStamp = 32460750
80 B9 46 42 98 10 BD 46 42 00 00 00 00 00 00 00 00 AA 2A 00 00 10 0A 6C 58 AB 08 00 00 00 00 00 00 00 ->trade complete

14333
/////////////////////////////////////////
E9 D7 38 03 00 00 00 01 GUID OF A
07 E2 91 03 00 00 00 01 GUID OF B
A asks B to trade
{CLIENT} Packet: (0x3863) CMSG_INITIATE_TRADE PacketSize = 6 TimeStamp = 14190240
67 90 E3 02 00 06 
server sends back to A confirmation of the received invite
{SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 33 TimeStamp = 14190989
5D 00 00 01 00 00 00 00 00 00 00 90 02 00 00 00 00 00 00 06 80 7F 0D 41 E3 03 00 00 00 29 B4 5E 2D 
//maybe some auto click by client on some popup
{CLIENT} Packet: (0x98CA) UNKNOWN PacketSize = 0 TimeStamp = 14191005

probably the other client accepted the trade
{SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 31 TimeStamp = 14191301
49 00 00 02 00 00 00 AB 2A 00 00 DB 00 09 00 00 00 0A 40 80 0D 41 0A 20 84 0D 41 2C 31 E9 00 
/////////////////////////////////////////
B asks A to trade
{SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 33 TimeStamp = 14208430
5D 00 2A 01 00 00 00 AB 2A 00 00 90 02 00 00 00 00 00 01 06 30 7F 0D 41 E3 07 E2 91 03 30 95 A8 4A compressed guid of the inviter
B accepts trade
{CLIENT} Packet: (0x0869) UNKNOWN PacketSize = 0 TimeStamp = 14208430

server lets B know that he received the previous packet
{SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 32 TimeStamp = 14208851
59 00 01 02 00 00 00 00 00 00 00 16 00 00 0A 00 00 00 DD E0 85 0D 41 BC B0 7D 0D 41 67 00 00 00 
/////////////////////////////////////////
*/
/*
we receive invite
{SERVER} Packet: (0xDB61) SMSG_TRADE_STATUS PacketSize = 33 TimeStamp = 14208430
5D 00 mask - 5 bits
2A junk
01 00 00 00 status ?
AB 2A 00 00 famous contant value or 0
90 - go2 B we are asking this guy to accept our trade
02 - go3 B we are asking this guy to accept our trade
00 00 00 00 00 00 - junk ?
06 - go0 B we are asking this guy to accept our trade
80 7F 0D 41 - magic float ? 
E3 - go1 B we are asking this guy to accept our trade
07 E2 91 03 lowguid of the other guy junk ?
30 95 A8 4A serializer ?
*/
	//right now trade initiator does not need this packet
/*	{
		sStackWorldPacket( data, SMSG_TRADE_STATUS, 44 + 10 );
		data << uint16( 0x59 ); // mask bit_2 might be go0, bit_0 might be go7
		data << uint8( 0 ); // junk
//		data << ObfuscateByte( GUID_bytes[6] );
		data << uint32( TRADE_STATUS_PROPOSED );	
		data << uint32( TRADE_ID_CONST ); //used a lot of times or 0
		data << ObfuscateByte( GUID_bytes[2] );
		data << ObfuscateByte( GUID_bytes[3] );
		data << uint8( 0 ); // junk
		data << uint32( 0x00000000 ); // highguid or junk
//		data << ObfuscateByte( GUID_bytes[7] );
		data << ObfuscateByte( GUID_bytes[0] );
		data << float( 0 ); // junk
		data << ObfuscateByte( GUID_bytes[1] );
		data << uint32( pTarget->GetLowGUID() ); // junk
		data << uint32( 0x00000000 ); // could be trade ID. Like A asks B, B refuses, A received back this number
		SendPacket( &data );
	}/**/
//	_player->SendTradeUpdate( 0 );
	//trade target does need this packet so he can auto reply with CMSG_BEGIN_TRADE
	{
		*(uint64*)GUID_bytes = _player->GetGUID();
		sStackWorldPacket( data, SMSG_TRADE_STATUS, 44 + 10 );
		data << uint16( 0x59 ); // mask bit_2 might be go0, bit_0 might be go7
		data << uint8( 0 ); // junk, can send 0 also
//		data << ObfuscateByte( GUID_bytes[6] );
		data << uint32( TRADE_STATUS_PROPOSED );	
		data << uint32( TRADE_ID_CONST ); //used a lot of times or 0, 
		data << ObfuscateByte( GUID_bytes[2] );
		data << ObfuscateByte( GUID_bytes[3] );
		data << uint8( 0 ); // junk
		data << uint32( 0x00000000 ); // highguid ? trade session counter ? junk ?
//		data << ObfuscateByte( GUID_bytes[7] );
		data << ObfuscateByte( GUID_bytes[0] );
		data << float( 0 ); // junk seems to be some float sometimes 
		data << ObfuscateByte( GUID_bytes[1] );
		data << uint32( _player->GetLowGUID() ); // lowguid ? junk ?
		data << uint32( 0 ); // could be trade ID. Like A asks B, B refuses, A received back this number. Or it could be time, global packet serializer
		pTarget->m_session->SendPacket( &data );
	}/**/
//	pTarget->SendTradeUpdate( 0 );
}
Пример #15
0
void WorldSession::FullLogin(Player* plr)
{
	DEBUG_LOG("WorldSession", "Fully loading player %u", plr->GetLowGUID());
	SetPlayer(plr);
	m_MoverWoWGuid.Init(plr->GetGUID());

	// copy to movement array
	plr->movement_packet[0] = m_MoverWoWGuid.GetNewGuidMask();
	memcpy(&plr->movement_packet[1], m_MoverWoWGuid.GetNewGuid(), m_MoverWoWGuid.GetNewGuidLen());

	/* world preload */
	packetSMSG_LOGIN_VERIFY_WORLD vwpck;
	vwpck.MapId = plr->GetMapId();
	vwpck.O = plr->GetOrientation();
	vwpck.X = plr->GetPositionX();
	vwpck.Y = plr->GetPositionY();
	vwpck.Z = plr->GetPositionZ();
	OutPacket( SMSG_LOGIN_VERIFY_WORLD, sizeof(packetSMSG_LOGIN_VERIFY_WORLD), &vwpck );

	// send voicechat state - active/inactive
	/*
	{SERVER} Packet: (0x03C7) UNKNOWN PacketSize = 2
	|------------------------------------------------|----------------|
	|00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |0123456789ABCDEF|
	|------------------------------------------------|----------------|
	|02 01							                 |..              |
	-------------------------------------------------------------------
	*/

	WorldPacket datab;

	datab.Initialize(SMSG_FEATURE_SYSTEM_STATUS);
	datab << uint8(2) << uint8(0);
	SendPacket(&datab);

	datab.Initialize(SMSG_LEARNED_DANCE_MOVES);
	datab << uint32(0);
	datab << uint32(0);
	SendPacket(&datab);

	plr->UpdateAttackSpeed();

	// Anti max level hack.
	if(sWorld.LevelCap_Custom_All && (plr->getLevel() > sWorld.LevelCap_Custom_All))
		plr->SetUInt32Value(UNIT_FIELD_LEVEL, sWorld.LevelCap_Custom_All);

	// Enable certain GM abilities on login.
	if(HasGMPermissions())
	{
		plr->bGMTagOn = true;
		plr->m_isGmInvisible = true;
		plr->m_invisible = true;
		if(CanUseCommand('z'))
		{
			plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_DEVELOPER);
			plr->triggerpass_cheat = true; // Enable for admins automatically.
		}
		else
			plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAG_GM);
	}

	// Make sure our name exists (for premade system)
	PlayerInfo * info = objmgr.GetPlayerInfo(plr->GetLowGUID());
	if(info == NULL)
	{
		info = new PlayerInfo;
		memset(info, 0, sizeof(PlayerInfo));
		info->cl = plr->getClass();
		info->gender = plr->getGender();
		info->guid = plr->GetLowGUID();
		info->name = strdup(plr->GetName());
		info->lastLevel = plr->getLevel();
		info->lastOnline = UNIXTIME;
		info->lastZone = plr->GetZoneId();
		info->race = plr->getRace();
		info->team = plr->GetTeam();
		objmgr.AddPlayerInfo(info);
	}
	plr->m_playerInfo = info;
	if(plr->m_playerInfo->guild)
	{
		plr->m_uint32Values[PLAYER_GUILDID] = plr->m_playerInfo->guild->GetGuildId();
		plr->m_uint32Values[PLAYER_GUILDRANK] = plr->m_playerInfo->guildRank->iId;
	}

	for(uint32 z = 0; z < NUM_ARENA_TEAM_TYPES; ++z)
	{
		if(plr->m_playerInfo->arenaTeam[z] != NULL)
		{
			plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*6), plr->m_playerInfo->arenaTeam[z]->m_id);
			if(plr->m_playerInfo->arenaTeam[z]->m_leader == plr->GetLowGUID())
				plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*6) + 1, 0);
			else
				plr->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (z*6) + 1, 1);
		}
	}

	info->m_loggedInPlayer = plr;

	// account data == UI config
	if(sWorld.m_useAccountData)
	{
		WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4);
		MD5Hash md5hash;
		data << uint32(UNIXTIME) << uint8(1) << uint32(0xEA);
		for (int i = 0; i < 8; i++)
		{
			AccountDataEntry* acct_data = GetAccountData(i);
			if(0xEA & (1 << i))
				data << uint32(acct_data->Time);
			md5hash.Initialize();
			md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz);
			md5hash.Finalize();
		}
		SendPacket(&data);
	}
	else
	{
		WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4+1+4+8*4);
		MD5Hash md5hash;
		data << uint32(UNIXTIME) << uint8(1) << uint32(0xEA);
		for (int i = 0; i < 8; i++)
		{
			if(0xEA & (1 << i))
				data << uint32(0);
			AccountDataEntry* acct_data = GetAccountData(i);
			if(acct_data)
			{
				md5hash.Initialize();
				md5hash.UpdateData((const uint8*)acct_data->data, acct_data->sz);
				md5hash.Finalize();
			}
		}
		SendPacket(&data);
	}

	// Set TIME OF LOGIN
	CharacterDatabase.Execute ("UPDATE characters SET online = 1 WHERE guid = %u" , plr->GetLowGUID());

	bool enter_world = true;
#ifndef CLUSTERING
	// Find our transporter and add us if we're on one.
	if(plr->m_TransporterGUID != 0)
	{
		Transporter* pTrans = objmgr.GetTransporter(GUID_LOPART(plr->m_TransporterGUID));
		if(pTrans)
		{
			if(plr->isDead())
			{
				plr->RemoteRevive();
			}

			float c_tposx = pTrans->GetPositionX() + plr->m_transportPosition->x;
			float c_tposy = pTrans->GetPositionY() + plr->m_transportPosition->y;
			float c_tposz = pTrans->GetPositionZ() + plr->m_transportPosition->z;
			if(plr->GetMapId() != pTrans->GetMapId())	// loaded wrong map
			{
				plr->SetMapId(pTrans->GetMapId());

				WorldPacket dataw(SMSG_NEW_WORLD, 20);
				dataw << pTrans->GetMapId() << c_tposx << c_tposy << c_tposz << plr->GetOrientation();
				SendPacket(&dataw);

				// shit is sent in worldport ack.
				enter_world = false;
			}

			plr->SetPosition(c_tposx, c_tposy, c_tposz, plr->GetOrientation(), false);
			plr->m_CurrentTransporter = pTrans;
			pTrans->AddPlayer(plr);
		}
	}
#endif

	if(plr->GetVehicle())
		plr->GetVehicle()->RemovePassenger(plr);

	DEBUG_LOG( "WorldSession","Player %s logged in.", plr->GetName());

	if(plr->GetTeam() == 1)
		sWorld.HordePlayers++;
	else
		sWorld.AlliancePlayers++;

	if(sWorld.SendMovieOnJoin && plr->m_FirstLogin && !HasGMPermissions())
		plr->SendCinematic(plr->myRace->cinematic_id);

	DEBUG_LOG( "WorldSession","Created new player for existing players (%s)", plr->GetName() );

	// Login time, will be used for played time calc
	plr->m_playedtime[2] = (uint32)UNIXTIME;

	//Issue a message telling all guild members that this player has signed on
	if(plr->IsInGuild())
	{
		Guild *pGuild = plr->m_playerInfo->guild;
		if(pGuild)
		{
			WorldPacket data(SMSG_GUILD_EVENT, 50);
			data << uint8(GUILD_EVENT_MOTD);
			data << uint8(0x01);
			if(pGuild->GetMOTD())
				data << pGuild->GetMOTD();
			else
				data << uint8(0);
			SendPacket(&data);

			pGuild->LogGuildEvent(GUILD_EVENT_HASCOMEONLINE, 1, plr->GetName());
		}
	}

	// Send online status to people having this char in friendlist (excluding GM's)
	if(!HasGMPermissions())
		plr->Social_TellFriendsOnline();

	// send friend list (for ignores)
	plr->Social_SendFriendList(7);

	// Send revision
	plr->BroadcastMessage("%sServer:|r%s Sandshroud Hearthstone|r %s r%u-%s-%s", MSG_COLOR_GOLD,
		MSG_COLOR_ORANGEY, MSG_COLOR_TORQUISEBLUE, BUILD_REVISION, ARCH, CONFIG);
	plr->BroadcastMessage("%sPlease report all bugs to |r%shttp://mantis.sandshroud.org|r", MSG_COLOR_GOLD, MSG_COLOR_TORQUISEBLUE);
	plr->BroadcastMessage("%sOnline Players:|r%s %u |r%sPeak:|r%s %u |r%sAccepted Connections:|r%s %u |r", MSG_COLOR_GOLD,
		MSG_COLOR_TORQUISEBLUE, sWorld.GetSessionCount(), MSG_COLOR_GOLD, MSG_COLOR_TORQUISEBLUE,
		sWorld.PeakSessionCount, MSG_COLOR_GOLD, MSG_COLOR_TORQUISEBLUE, sWorld.mAcceptedConnections);

	plr->BroadcastMessage("%sServer Uptime:|r%s %s|r", MSG_COLOR_GOLD, MSG_COLOR_TORQUISEBLUE, sWorld.GetUptimeString().c_str());

	// send to gms
	if(HasGMPermissions())
		sWorld.SendMessageToGMs(this, "%s%s %s (%s) is now online.|r", MSG_COLOR_GOLD, CanUseCommand('z') ? "Admin" : "GameMaster", plr->GetName(), GetAccountNameS(), GetPermissions());

	// Send first line of MOTD
	WorldPacket datat(SMSG_MOTD, 10);
	datat << uint32(0x04);
	datat << sWorld.GetMotd();
	SendPacket(&datat);

	// Send second line of MOTD
	WorldPacket datat2(SMSG_MOTD, 10);
	datat2 << uint32(0x04);
	datat2 << sWorld.GetMotd2();
	SendPacket(&datat2);

	//Set current RestState
	if( plr->m_isResting) 		// We are in a resting zone, turn on Zzz
		plr->ApplyPlayerRestState(true);

	//Check if there is a time difference between lastlogoff and now
	if( plr->m_timeLogoff > 0 && plr->GetUInt32Value(UNIT_FIELD_LEVEL) < plr->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL))	// if timelogoff = 0 then it's the first login
	{
		uint32 currenttime = (uint32)UNIXTIME;
		uint32 timediff = currenttime - plr->m_timeLogoff;

		//Calculate rest bonus
		if( timediff > 0 )
			plr->AddCalculatedRestXP(timediff);
	}

	sHookInterface.OnFullLogin(plr);

	if(info->m_Group)
		info->m_Group->Update();

	if(!sWorld.m_blockgmachievements || !HasGMPermissions())
	{
		// Retroactive: Level achievement
		plr->GetAchievementInterface()->HandleAchievementCriteriaLevelUp( plr->getLevel() );

		// Send achievement data!
		if( plr->GetAchievementInterface()->HasAchievements() )
		{
			WorldPacket * data = plr->GetAchievementInterface()->BuildAchievementData();
			plr->CopyAndSendDelayedPacket(data);
			delete data;
		}
	}

	if(enter_world && !plr->GetMapMgr())
		plr->AddToWorld(true);

	sTracker.CheckPlayerForTracker(plr, true);

	// If we have the talent, it returns anyway, so just call the function.
	plr->ResetTitansGrip();

	if(plr->GetItemInterface())
		plr->GetItemInterface()->CheckAreaItems();
	objmgr.AddPlayer(plr);
}