示例#1
0
void MapMgr::LoadAllCells()
{
	// eek
	MapCell* cellInfo;
	CellSpawns* spawns;

	for(uint32 x = 0 ; x < _sizeX ; x ++)
	{
		for(uint32 y = 0 ; y < _sizeY ; y ++)
		{
			cellInfo = GetCell(x , y);

			if(!cellInfo)
			{
				// Cell doesn't exist, create it.
				// There is no spoon. Err... cell.
				cellInfo = Create(x , y);
				cellInfo->Init(x , y , this);
				LOG_DETAIL("Created cell [%u,%u] on map %u (instance %u)." , x , y , _mapId , m_instanceID);
				cellInfo->SetActivity(true);
				_map->CellGoneActive(x , y);
				ARCEMU_ASSERT(!cellInfo->IsLoaded());

				spawns = _map->GetSpawnsList(x , y);
				if(spawns)
					cellInfo->LoadObjects(spawns);
			}
			else
			{
				// Cell exists, but is inactive
				if(!cellInfo->IsActive())
				{
					LOG_DETAIL("Activated cell [%u,%u] on map %u (instance %u).", x, y, _mapId, m_instanceID);
					_map->CellGoneActive(x , y);
					cellInfo->SetActivity(true);

					if(!cellInfo->IsLoaded())
					{
						//LOG_DETAIL("Loading objects for Cell [%u][%u] on map %u (instance %u)...",
						//	posX, posY, this->_mapId, m_instanceID);
						spawns = _map->GetSpawnsList(x , y);
						if(spawns)
							cellInfo->LoadObjects(spawns);
					}
				}
			}
		}
	}
}
示例#2
0
void WorldSession::HandleQuestPushResult(WorldPacket & recvPacket)
{
	CHECK_INWORLD_RETURN

	uint64 guid;
	uint8 msg;
	recvPacket >> guid;
	uint32 questid = 0;
	if(recvPacket.size() >= 13)  //VLack: The client can send a 13 byte packet, where the result message is the 13th byte, and we have some data before it... Usually it is the quest id, but I have seen this as uint32(0) too.
		recvPacket >> questid;
	recvPacket >> msg;

	LOG_DETAIL("WORLD: Received MSG_QUEST_PUSH_RESULT");

	if(GetPlayer()->GetQuestSharer())
	{
		Player* pPlayer = objmgr.GetPlayer(GetPlayer()->GetQuestSharer());
		if(pPlayer)
		{
			WorldPacket data(MSG_QUEST_PUSH_RESULT, 9);
			if(recvPacket.size() >= 13)  //VLack: In case the packet was the longer one, its guid is the quest giver player, thus in the response we have to tell him that _this_ player reported the particular state. I think this type of response could also eliminate our SetQuestSharer/GetQuestSharer mess and its possible lock up conditions...
				data << uint64(_player->GetGUID());
			else
				data << uint64(guid);
			data << uint8(msg);
			pPlayer->GetSession()->SendPacket(&data);
			GetPlayer()->SetQuestSharer(0);
		}
	}
}
示例#3
0
void Player::SendInitialLogonPackets()
{
    // Initial Packets... they seem to be re-sent on port.
    //m_session->OutPacket(SMSG_SET_REST_START_OBSOLETE, 4, &m_timeLogoff); // Seem to be unused by client

    StackWorldPacket<32> data(SMSG_BINDPOINTUPDATE);

    data << float(m_bind_pos_x);
    data << float(m_bind_pos_y);
    data << float(m_bind_pos_z);
    data << uint32(m_bind_mapid);
    data << uint32(m_bind_zoneid);

    m_session->SendPacket(&data);

    //Proficiencies
    SendSetProficiency(4, armor_proficiency);
    SendSetProficiency(2, weapon_proficiency);

    //Tutorial Flags
    data.Initialize(SMSG_TUTORIAL_FLAGS);

    for (uint8 i = 0; i < 8; i++)
        data << uint32(m_Tutorials[i]);

    m_session->SendPacket(&data);

    smsg_TalentsInfo(false);
    smsg_InitialSpells();

    data.Initialize(SMSG_SEND_UNLEARN_SPELLS);
    data << uint32(0); // count, for (count) uint32;
    GetSession()->SendPacket(&data);

    SendInitialActions();
    smsg_InitialFactions();

    data.Initialize(SMSG_LOGIN_SETTIMESPEED);

    data << uint32(Arcemu::Util::MAKE_GAME_TIME());
    data << float(0.0166666669777748f);    // Normal Game Speed
    data << uint32(0);   // 3.1.2

    m_session->SendPacket(&data);

    // cebernic for speedhack bug
    m_lastRunSpeed = 0;
    UpdateSpeed();

    WorldPacket ArenaSettings(SMSG_UPDATE_WORLD_STATE, 16);

    ArenaSettings << uint32(0xC77);
    ArenaSettings << uint32(sWorld.Arena_Progress);
    ArenaSettings << uint32(0xF3D);
    ArenaSettings << uint32(sWorld.Arena_Season);

    m_session->SendPacket(&ArenaSettings);

    LOG_DETAIL("WORLD: Sent initial logon packets for %s.", GetName());
}
示例#4
0
void MapMgr::UnloadCell(uint32 x, uint32 y)
{
	MapCell* c = GetCell(x, y);
	if(c == NULL || c->HasPlayers() || _CellActive(x, y) || !c->IsUnloadPending()) return;

	LOG_DETAIL("Unloading Cell [%u][%u] on map %u (instance %u)...",
	           x, y, _mapId, m_instanceID);

	c->Unload();
}
示例#5
0
//////////////////////////////////////////////////////////////
/// This function handles MSG_CORPSE_QUERY:
//////////////////////////////////////////////////////////////
void WorldSession::HandleCorpseQueryOpcode(WorldPacket &recv_data)
{
	CHECK_INWORLD_RETURN

	LOG_DETAIL("WORLD: Received MSG_CORPSE_QUERY");

	Corpse *pCorpse;
	WorldPacket data(MSG_CORPSE_QUERY, 25);
	MapInfo *pMapinfo;

	pCorpse = objmgr.GetCorpseByOwner(GetPlayer()->GetLowGUID());
	if(pCorpse)
	{
		pMapinfo = WorldMapInfoStorage.LookupEntry(pCorpse->GetMapId());
		if(pMapinfo)
		{
			if(pMapinfo->type == INSTANCE_NULL || pMapinfo->type == INSTANCE_BATTLEGROUND)
			{
				data << uint8(0x01); //show ?
				data << pCorpse->GetMapId(); // mapid (that tombstones shown on)
				data << pCorpse->GetPositionX();
				data << pCorpse->GetPositionY();
				data << pCorpse->GetPositionZ();
				data << pCorpse->GetMapId(); //instance mapid (needs to be same as mapid to be able to recover corpse)
				data << uint32(0);
				SendPacket(&data);
			}
			else
			{
				data << uint8(0x01); //show ?
				data << pMapinfo->repopmapid; // mapid (that tombstones shown on)
				data << pMapinfo->repopx;
				data << pMapinfo->repopy;
				data << pMapinfo->repopz;
				data << pCorpse->GetMapId(); //instance mapid (needs to be same as mapid to be able to recover corpse)
				data << uint32(0);
				SendPacket(&data);
			}
		}
		else
		{

			data << uint8(0x01); //show ?
			data << pCorpse->GetMapId(); // mapid (that tombstones shown on)
			data << pCorpse->GetPositionX();
			data << pCorpse->GetPositionY();
			data << pCorpse->GetPositionZ();
			data << pCorpse->GetMapId(); //instance mapid (needs to be same as mapid to be able to recover corpse)
			data << uint32(0);
			SendPacket(&data);

		}
	}
}
示例#6
0
void AddonMgr::SaveToDB()
{
	LOG_DETAIL("AddonMgr: Saving any new addons discovered in this session to database.");

	KnownAddonsItr itr;

	for(itr = mKnownAddons.begin(); itr != mKnownAddons.end(); ++itr)
	{
		if(itr->second->isNew)
		{
			LOG_DETAIL("Saving new addon %s", itr->second->name.c_str());
			std::stringstream ss;
			ss << "INSERT INTO clientaddons (name, crc, banned, showinlist) VALUES(\""
			   << WorldDatabase.EscapeString(itr->second->name) << "\",\""
			   << itr->second->crc << "\",\""
			   << itr->second->banned << "\",\""
			   << itr->second->showinlist << "\");";

			WorldDatabase.Execute(ss.str().c_str());
		}
	}
}
示例#7
0
int _tmain(int argc, _TCHAR* argv[])
{
    oLog::initialise();
    sLog.Init( 5, LOGON_LOG );

    LOG_DETAIL( "服务器启动..." );
    CNet net;
    if ( !net.Startup() )
    {
        return -1;
    }

    CServer server;
    CClient client;


    net.Listen( 6000, &server );

    net.Connect( "127.0.0.1", 6000, &client );

    LOG_DETAIL( "%s", "welcome, the serve is started..." );

    while( 1 )
    {
        net.Process();
        server.Process();
        client.Process();

    }

    net.Clearup();

    LOG_DETAIL( "服务器退出..." );

    sLog.Close();
    oLog::release();
    return 0;
}
示例#8
0
文件: Level1.cpp 项目: dberga/arcbliz
bool ChatHandler::HandleGMAnnounceCommand(const char* args, WorldSession* m_session)
{
	if(!*args)
	{
		LOG_DETAIL("ERROR: HandleGMAnnounceCommand !args = failed");
		return false;
	}

	char GMAnnounce[1024];
	snprintf(GMAnnounce, 1024, MSG_COLOR_RED "[Team]" MSG_COLOR_GREEN " |Hplayer:%s|h[%s]|h:" MSG_COLOR_YELLOW " %s", m_session->GetPlayer()->GetName(), m_session->GetPlayer()->GetName(), args);
	sWorld.SendGMWorldText(GMAnnounce);
	sGMLog.writefromsession(m_session, "used team announce command, [%s]", args);
	return true;
}
示例#9
0
extern "C" VALUE update_node_bayeux( VALUE self, VALUE node, VALUE value )
{
    const pubsub::node_name node_name  = hash_to_node( node );
    const json::value       node_value = ruby_to_json( value, node_name );

    LOG_DETAIL( log_context << "update: " << node_name << " to " << node_value );

    bayeux_server* server_ptr = 0;
    Data_Get_Struct( self, bayeux_server, server_ptr );
    assert( server_ptr );

    server_ptr->update_node( node_name, node_value );

    return self;
}
示例#10
0
void LogonCommHandler::UpdateSockets()
{
	mapLock.Acquire();

	map<LogonServer*, LogonCommClientSocket*>::iterator itr = logons.begin();
	LogonCommClientSocket* cs;
	uint32 t = (uint32)UNIXTIME;
	for(; itr != logons.end(); ++itr)
	{
		cs = itr->second;
		if(cs != 0)
		{
			if(!pings) continue;

			if(cs->IsDeleted() || !cs->IsConnected())
			{
				cs->_id = 0;
				itr->second = 0;
				continue;
			}

			if(cs->last_pong < t && ((t - cs->last_pong) > 60))
			{
				// no pong for 60 seconds -> remove the socket
				LOG_DETAIL(" >> realm id %u connection dropped due to pong timeout.", (unsigned int)itr->first->ID);
				cs->_id = 0;
				cs->Disconnect();
				itr->second = 0;
				continue;
			}

			if((t - cs->last_ping) > 15)
			{
				// send a ping packet.
				cs->SendPing();
			}
		}
		else
		{
			// check retry time
			if(t >= itr->first->RetryTime)
			{
				Connect(itr->first);
			}
		}
	}
	mapLock.Release();
}
示例#11
0
void WorldSocket::_HandlePing(WorldPacket* recvPacket)
{
	uint32 ping;
	if(recvPacket->size() < 4)
	{
		LOG_DETAIL("ERROR: Socket closed due to incomplete ping packet.");
		Disconnect();
		return;
	}

	*recvPacket >> ping;
	*recvPacket >> _latency;

	if(mSession)
	{
		mSession->_latency = _latency;
		mSession->m_lastPing = (uint32)UNIXTIME;

		// reset the move time diff calculator, don't worry it will be re-calculated next movement packet.
		mSession->m_clientTimeDelay = 0;
	}

	OutPacket(SMSG_PONG, 4, &ping);

#ifdef WIN32
	// Dynamically change nagle buffering status based on latency.
	//if(_latency >= 250)
	// I think 350 is better, in a MMO 350 latency isn't that big that we need to worry about reducing the number of packets being sent.
	if(_latency >= 350)
	{
		if(!m_nagleEanbled)
		{
			u_long arg = 0;
			setsockopt(GetFd(), 0x6, 0x1, (const char*)&arg, sizeof(arg));
			m_nagleEanbled = true;
		}
	}
	else
	{
		if(m_nagleEanbled)
		{
			u_long arg = 1;
			setsockopt(GetFd(), 0x6, 0x1, (const char*)&arg, sizeof(arg));
			m_nagleEanbled = false;
		}
	}
#endif
}
示例#12
0
void WorldSocket::_HandleAuthSession(WorldPacket* recvPacket)
{
	std::string account;
	uint32 unk2, unk3;
	uint64 unk4;
	uint32 unk5, unk6, unk7;

	_latency = getMSTime() - _latency;

	try
	{
		*recvPacket >> mClientBuild;
		*recvPacket >> unk2;
		*recvPacket >> account;
		*recvPacket >> unk3;
		*recvPacket >> mClientSeed;
		*recvPacket >> unk4;
		*recvPacket >> unk5;
		*recvPacket >> unk6;
		*recvPacket >> unk7;
	}
	catch(ByteBuffer::error &)
	{
		LOG_DETAIL("Incomplete copy of AUTH_SESSION Received.");
		return;
	}

	// Send out a request for this account.
	mRequestID = sLogonCommHandler.ClientConnected(account, this);

	if(mRequestID == 0xFFFFFFFF)
	{
		Disconnect();
		return;
	}

	// shitty hash !
	m_fullAccountName = new string(account);

	// Set the authentication packet
	pAuthenticationPacket = recvPacket;
}
示例#13
0
	bool EquipmentSetMgr::LoadfromDB(QueryResult* result)
	{
		if(result == NULL)
			return false;

		uint32 setcount = 0;
		EquipmentSet* set = NULL;
		Field* fields = NULL;

		do
		{

			if(setcount >= 10)
			{
				LOG_DETAIL("ERROR: There were more than 10 equipment sets for GUID: %u", ownerGUID);
				return true;
			}

			fields = result->Fetch();

			set = new EquipmentSet();
			if(set == NULL)
				return false;

			set->SetGUID = fields[ 1 ].GetUInt32();
			set->SetID = fields[ 2 ].GetUInt32();
			set->SetName = fields[ 3 ].GetString();
			set->IconName = fields[ 4 ].GetString();

			for(uint32 i = 0; i < set->ItemGUID.size(); ++i)
				set->ItemGUID[ i ] = fields[ 5 + i ].GetUInt32();

			EquipmentSets.insert(std::pair< uint32, EquipmentSet* >(set->SetGUID, set));
			set = NULL;
			setcount++;

		}
		while(result->NextRow());


		return true;
	}
示例#14
0
void IPBanner::Reload()
{

    listBusy.Acquire();
    banList.clear();
    QueryResult* result = sLogonSQL->Query("SELECT ip, expire FROM ipbans");
    if(result != NULL)
    {
        do
        {
            IPBan ipb;
            std::string smask = "32";
            std::string ip = result->Fetch()[0].GetString();
            std::string::size_type i = ip.find("/");
            std::string stmp = ip.substr(0, i);
            if(i == std::string::npos)
            {
                LOG_DETAIL("IP ban \"%s\" netmask not specified. assuming /32", ip.c_str());
            }
            else
                smask = ip.substr(i + 1);

            unsigned int ipraw = MakeIP(stmp.c_str());
            unsigned int ipmask = atoi(smask.c_str());
            if(ipraw == 0 || ipmask == 0)
            {
                LOG_ERROR("IP ban \"%s\" could not be parsed. Ignoring", ip.c_str());
                continue;
            }

            ipb.Bytes = static_cast<unsigned char>(ipmask);
            ipb.Mask = ipraw;
            ipb.Expire = result->Fetch()[1].GetUInt32();
            ipb.db_ip = ip;
            banList.push_back(ipb);

        }
        while(result->NextRow());
        delete result;
    }
    listBusy.Release();
}
示例#15
0
LootMgr::~LootMgr()
{
	LOG_DETAIL("  Deleting Loot Tables...");
	for(LootStore::iterator iter = CreatureLoot.begin(); iter != CreatureLoot.end(); ++iter)
		delete [] iter->second.items;

	for(LootStore::iterator iter = FishingLoot.begin(); iter != FishingLoot.end(); ++iter)
		delete [] iter->second.items;

	for(LootStore::iterator iter = SkinningLoot.begin(); iter != SkinningLoot.end(); ++iter)
		delete [] iter->second.items;

	for(LootStore::iterator iter = GOLoot.begin(); iter != GOLoot.end(); ++iter)
		delete [] iter->second.items;

	for(LootStore::iterator iter = ItemLoot.begin(); iter != ItemLoot.end(); ++iter)
		delete [] iter->second.items;

	for(LootStore::iterator iter = PickpocketingLoot.begin(); iter != PickpocketingLoot.end(); ++iter)
		delete [] iter->second.items;
}
示例#16
0
void InformationCore::CheckServers()
{
    serverSocketLock.Acquire();

    std::set<LogonCommServerSocket*>::iterator itr, it2;
    LogonCommServerSocket* s;
    for(itr = m_serverSockets.begin(); itr != m_serverSockets.end();)
    {
        s = *itr;
        it2 = itr;
        ++itr;

        if(!IsServerAllowed(s->GetRemoteAddress().s_addr))
        {
            LOG_DETAIL("Disconnecting socket: %s due to it no longer being on an allowed IP.", s->GetRemoteIP().c_str());
            s->Disconnect();
        }
    }

    serverSocketLock.Release();
}
示例#17
0
//////////////////////////////////////////////////////////////
/// This function handles CMSG_GOSSIP_SELECT_OPTION:
//////////////////////////////////////////////////////////////
void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recv_data)
{
	CHECK_INWORLD_RETURN

	uint32 option;
	uint32 unk24;
	uint64 guid;

	recv_data >> guid >> unk24 >> option;

	LOG_DETAIL("WORLD: CMSG_GOSSIP_SELECT_OPTION Option %i Guid %.8X", option, guid);
	Arcemu::Gossip::Script* script = NULL;
	uint32 guidtype = GET_TYPE_FROM_GUID(guid);

	Object* qst_giver;
	if(guidtype == HIGHGUID_TYPE_ITEM)	//Item objects are retrieved differently.
	{
		qst_giver = GetPlayer()->GetItemInterface()->GetItemByGUID(guid);
		if(qst_giver != NULL)
			script = Arcemu::Gossip::Script::GetInterface(TO_ITEM(qst_giver));
	}
	else
		qst_giver = GetPlayer()->GetMapMgr()->_GetObject(guid);
	if(qst_giver != NULL)
	{
		if(guidtype == HIGHGUID_TYPE_UNIT)
			script = Arcemu::Gossip::Script::GetInterface(TO_CREATURE(qst_giver));
		else if(guidtype == HIGHGUID_TYPE_GAMEOBJECT)
			script = Arcemu::Gossip::Script::GetInterface(TO_GAMEOBJECT(qst_giver));
	}
	if(script != NULL)
	{
		string str;
		if(recv_data.rpos() != recv_data.wpos())
			recv_data >> str;
		if(str.length() > 0)
			script->OnSelectOption(qst_giver, GetPlayer() , option, str.c_str());
		else
			script->OnSelectOption(qst_giver, GetPlayer() , option, NULL);
	}
示例#18
0
/*** Signal Handler ***/
void _OnSignal(int s)
{
	switch (s)
	{
#ifndef WIN32
	case SIGHUP:
	   {
		   LOG_DETAIL("Received SIGHUP signal, reloading accounts.");
		   AccountMgr::getSingleton().ReloadAccounts(true);
	   }break;
#endif
	case SIGINT:
	case SIGTERM:
	case SIGABRT:
#ifdef _WIN32
	case SIGBREAK:
#endif
		mrunning.SetVal(false);
		break;
	}

	signal(s, _OnSignal);
}
示例#19
0
void WorldSocket::OutPacket(uint16 opcode, size_t len, const void* data)
{
	OUTPACKET_RESULT res;
	if((len + 10) > WORLDSOCKET_SENDBUF_SIZE)
	{
		LOG_DETAIL("ERROR: WARNING: Tried to send a packet of %u bytes (which is too large) to a socket. Opcode was: %u (0x%03X)", (unsigned int)len, (unsigned int)opcode, (unsigned int)opcode);
		return;
	}

	res = _OutPacket(opcode, len, data);
	if(res == OUTPACKET_RESULT_SUCCESS)
		return;

	if(res == OUTPACKET_RESULT_NO_ROOM_IN_BUFFER)
	{
		/* queue the packet */
		queueLock.Acquire();
		WorldPacket* pck = new WorldPacket(opcode, len);
		if(len) pck->append((const uint8*)data, len);
		_queue.Push(pck);
		queueLock.Release();
	}
}
示例#20
0
bool DayWatcherThread::runThread()
{
    LOG_DETAIL("Started.");
    currenttime = UNIXTIME;
    dupe_tm_pointer(localtime(&currenttime), &local_currenttime);
    load_settings();
    set_tm_pointers();
    m_busy = false;

    while (GetThreadState() != THREADSTATE_TERMINATE)
    {
        m_busy = true;
        currenttime = UNIXTIME;
        dupe_tm_pointer(localtime(&currenttime), &local_currenttime);

        if (has_timeout_expired(&local_currenttime, &local_last_arena_time, arena_period))
            update_arena();

        if (has_timeout_expired(&local_currenttime, &local_last_daily_time, daily_period))
            update_daily();

        if (m_dirty)
            update_settings();

        m_busy = false;
        if (GetThreadState() == THREADSTATE_TERMINATE)
            break;

        cond.Wait(THREAD_LOOP_INTERVAL * 1000);

        if (!m_running)
            break;
    }

    return true;
}
示例#21
0
//////////////////////////////////////////////////////////////
/// This function handles CMSG_CREATURE_QUERY:
//////////////////////////////////////////////////////////////
void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data )
{
	CHECK_INWORLD_RETURN

	CHECK_PACKET_SIZE(recv_data, 12);

	WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 250); //VLack: thanks Aspire, this was 146 before
	uint32 entry;
	uint64 guid;
	CreatureInfo *ci;

	recv_data >> entry;
	recv_data >> guid;

	if(entry == 300000)
	{
		data << (uint32)entry;
		data << "WayPoint";
		data << uint8(0) << uint8(0) << uint8(0);
		data << "Level is WayPoint ID";
		for(uint32 i = 0; i < 8;i++)
		{
			data << uint32(0);
		}
		data << uint8(0);  
	}
	else
	{
		ci = CreatureNameStorage.LookupEntry(entry);
		if(ci == NULL)
			return;

		LocalizedCreatureName * lcn = (language>0) ? sLocalizationMgr.GetLocalizedCreatureName(entry, language) : NULL;

		if(lcn == NULL)
		{
			LOG_DETAIL("WORLD: CMSG_CREATURE_QUERY '%s'", ci->Name);
			data << (uint32)entry;
			data << ci->Name;       // name of the creature
			data << uint8(0);       // name2, always seems to be empty
            data << uint8(0);       // name3, always seems to be empty
            data << uint8(0);       // name4, always seems to be empty
			data << ci->SubName;    // this is the title/guild of the creature
		}
		else
		{
			LOG_DETAIL("WORLD: CMSG_CREATURE_QUERY '%s' (localized to %s)", ci->Name, lcn->Name);
			data << (uint32)entry;
			data << lcn->Name;
			data << uint8(0); 
            data << uint8(0); 
            data << uint8(0);
			data << lcn->SubName;
		}
		data << ci->info_str;     //!!! this is a string in 2.3.0 Example: stormwind guard has : "Direction"
		data << ci->Flags1;       // flags like skinnable
		data << ci->Type;         // humanoid, beast, etc
		data << ci->Family;       // petfamily
		data << ci->Rank;         // normal, elite, etc
        data << ci->killcredit[0];  // quest kill credit 1
        data << ci->killcredit[1];  // quest kill credit 2
		data << ci->Male_DisplayID;
		data << ci->Female_DisplayID;
		data << ci->Male_DisplayID2;
		data << ci->Female_DisplayID2;
		data << ci->unkfloat1;
		data << ci->unkfloat2;
		data << ci->Leader;         // faction leader

        // these are the 6 seperate quest items a creature can drop
		for(uint32 i = 0; i < 6; ++i)
		{
			data << uint32(ci->QuestItems[i]);
		}
        data << ci->waypointid;
	}

	SendPacket( &data );
}
示例#22
0
void WorldSession::HandleSpellClick(WorldPacket & recvPacket)
{
	CHECK_INWORLD_RETURN

	LOG_DETAIL("WORLD: got CMSG_SPELLCLICK packet, data length = %i", recvPacket.size());

	if(_player->getDeathState() == CORPSE)
		return;

	uint64 target_guid; // this will store the guid of the object we are going to use it's spell. There must be a dbc that indicates what spells a unit has

	recvPacket >> target_guid;

	//we have only 1 example atm for entry : 28605
	Unit* target_unit = _player->GetMapMgr()->GetUnit(target_guid);

	if(!target_unit)
		return;

	if( !_player->isInRange( target_unit, MAX_INTERACTION_RANGE ) )
		return;

	if( target_unit->IsVehicle() ){
		if( target_unit->GetVehicleComponent() != NULL )
			target_unit->GetVehicleComponent()->AddPassenger( _player );
		return;
	}

	uint32 creature_id = target_unit->GetEntry();
	uint32 cast_spell_id = 0;

	if(!_player->HasAurasWithNameHash(SPELL_HASH_LIGHTWELL_RENEW) && target_unit->RemoveAura(59907))
	{
		SpellClickSpell *sp = SpellClickSpellStorage.LookupEntry( creature_id );
		if( sp == NULL ){
			if( target_unit->IsCreature() ){
				Creature *c = TO< Creature* >( target_unit );
				
				sChatHandler.BlueSystemMessage( this, "NPC Id %u ( %s ) has no spellclick spell associated with it.", c->GetProto()->Id, c->GetCreatureInfo()->Name  );
				LOG_DETAIL("ERROR: Spellclick packet received for creature %u but there is no spell associated with it.", creature_id );
				return;
			}
		}

		cast_spell_id = sp->SpellID;

		target_unit->CastSpell(_player, cast_spell_id, true);

		if(!target_unit->HasAura(59907))
			TO_CREATURE(target_unit)->Despawn(0, 0); //IsCreature() check is not needed, refer to r2387 and r3230

		return;
	}
	
	SpellClickSpell *sp = SpellClickSpellStorage.LookupEntry( creature_id );
	if( sp == NULL ){
		if( target_unit->IsCreature() ){
			Creature *c = TO< Creature* >( target_unit );

			sChatHandler.BlueSystemMessage( this, "NPC Id %u ( %s ) has no spellclick spell associated with it.", c->GetProto()->Id, c->GetCreatureInfo()->Name  );
			LOG_DETAIL("ERROR: Spellclick packet received for creature %u but there is no spell associated with it.", creature_id );
			return;
		}
	}

	cast_spell_id = sp->SpellID;

	if(cast_spell_id == 0)
		return;

	SpellEntry* spellInfo = dbcSpell.LookupEntryForced(cast_spell_id);
	if(spellInfo == NULL)
		return;
	Spell* spell = sSpellFactoryMgr.NewSpell(_player, spellInfo, false, NULL);
	SpellCastTargets targets(target_guid);
	spell->prepare(&targets);
}
示例#23
0
//////////////////////////////////////////////////////////////
/// This function handles CMSG_GAMEOBJECT_QUERY:
//////////////////////////////////////////////////////////////
void WorldSession::HandleGameObjectQueryOpcode( WorldPacket & recv_data )
{
	CHECK_INWORLD_RETURN

	CHECK_PACKET_SIZE(recv_data, 12);
	WorldPacket data(SMSG_GAMEOBJECT_QUERY_RESPONSE, 900);

	uint32 entryID;
	uint64 guid;
	GameObjectInfo *goinfo;
	

	recv_data >> entryID;
	recv_data >> guid;

	LOG_DETAIL("WORLD: CMSG_GAMEOBJECT_QUERY '%u'", entryID);

	goinfo = GameObjectNameStorage.LookupEntry(entryID);
	if(goinfo == NULL)
		return;

	LocalizedGameObjectName * lgn = (language>0) ? sLocalizationMgr.GetLocalizedGameObjectName(entryID, language) : NULL;
    
	data << entryID;                // unique identifier of the GO template
	data << goinfo->Type;           // type of the gameobject
	data << goinfo->DisplayID;      // displayid/modelid of the gameobject

    // Name of the gameobject
	if(lgn)
		data << lgn->Name;
	else
		data << goinfo->Name;

	data << uint8( 0 );            // name2, always seems to be empty
	data << uint8( 0 );            // name3, always seems to be empty
	data << uint8( 0 );            // name4, always seems to be empty
	data << goinfo->Category;       // Category string of the GO, like "attack", "pvp", "point", etc
	data << goinfo->Castbartext;    // text displayed when using the go, like "collecting", "summoning" etc
	data << goinfo->Unkstr;
	data << goinfo->SpellFocus;     // spellfocus id, ex.: spell casted when interacting with the GO
	data << goinfo->sound1;
	data << goinfo->sound2;
	data << goinfo->sound3;
	data << goinfo->sound4;
	data << goinfo->sound5;
	data << goinfo->sound6;
	data << goinfo->sound7;
	data << goinfo->sound8;
	data << goinfo->sound9;
	data << goinfo->Unknown1;
	data << goinfo->Unknown2;
	data << goinfo->Unknown3;
	data << goinfo->Unknown4;
	data << goinfo->Unknown5;
	data << goinfo->Unknown6;
	data << goinfo->Unknown7;
	data << goinfo->Unknown8;
	data << goinfo->Unknown9;
	data << goinfo->Unknown10;
	data << goinfo->Unknown11;
	data << goinfo->Unknown12;
	data << goinfo->Unknown13;
	data << goinfo->Unknown14;
	data << float(goinfo->Size);       // scaling of the GO

    // questitems that the go can contain
	for(uint32 i = 0; i < 6; ++i)
	{
		data << uint32(goinfo->QuestItems[i]);
		
	}

	SendPacket( &data );
}
示例#24
0
void AuthSocket::HandleChallenge()
{
	// No header
	if(readBuffer.GetContiguiousBytes() < 4)
	{
		LOG_ERROR("[AuthChallenge] Packet has no header. Refusing to handle.");
		return;
	}

	// Check the rest of the packet is complete.
	uint8* ReceiveBuffer = (uint8*)readBuffer.GetBufferStart();

	uint16 full_size = *(uint16*)&ReceiveBuffer[2];


	LOG_DETAIL("[AuthChallenge] got header, body is %u bytes", full_size);

	if(readBuffer.GetSize() < uint32(full_size + 4))
	{
		LOG_ERROR("[AuthChallenge] Packet is smaller than expected, refusing to handle");
		return;
	}

	// Copy the data into our cached challenge structure
	if(full_size > sizeof(sAuthLogonChallenge_C))
	{
		LOG_ERROR("[AuthChallenge] Packet is larger than expected, refusing to handle!");
		Disconnect();
		return;
	}

	LOG_DEBUG("[AuthChallenge] got a complete packet.");

	//memcpy(&m_challenge, ReceiveBuffer, full_size + 4);
	//RemoveReadBufferBytes(full_size + 4, true);
	readBuffer.Read(&m_challenge, full_size + 4);

	// Check client build.

	uint16 build = m_challenge.build;

	// Check client build.
	if(build > LogonServer::getSingleton().max_build)
	{
		// wtf?
		LOG_DETAIL("[AuthChallenge] Client %s has wrong version. More up to date than server. Server: %u, Client: %u", GetRemoteIP().c_str(), LogonServer::getSingleton().max_build, m_challenge.build);
		SendChallengeError(CE_WRONG_BUILD_NUMBER);
		return;
	}

	if(build < LogonServer::getSingleton().min_build)
	{
		// can we patch?
		char flippedloc[5] = {0, 0, 0, 0, 0};
		flippedloc[0] = m_challenge.country[3];
		flippedloc[1] = m_challenge.country[2];
		flippedloc[2] = m_challenge.country[1];
		flippedloc[3] = m_challenge.country[0];

		m_patch = PatchMgr::getSingleton().FindPatchForClient(build, flippedloc);
		if(m_patch == NULL)
		{
			// could not find a valid patch
			LOG_DETAIL("[AuthChallenge] Client %s has wrong version. More out of date than server. Server: %u, Client: %u", GetRemoteIP().c_str(), LogonServer::getSingleton().min_build, m_challenge.build);
			SendChallengeError(CE_WRONG_BUILD_NUMBER);
			return;
		}

		Log.Debug("Patch", "Selected patch %u%s for client.", m_patch->Version, m_patch->Locality);


		uint8 response[119] =
		{
			0x00, 0x00, 0x00, 0x72, 0x50, 0xa7, 0xc9, 0x27, 0x4a, 0xfa, 0xb8, 0x77, 0x80, 0x70, 0x22,
			0xda, 0xb8, 0x3b, 0x06, 0x50, 0x53, 0x4a, 0x16, 0xe2, 0x65, 0xba, 0xe4, 0x43, 0x6f, 0xe3,
			0x29, 0x36, 0x18, 0xe3, 0x45, 0x01, 0x07, 0x20, 0x89, 0x4b, 0x64, 0x5e, 0x89, 0xe1, 0x53,
			0x5b, 0xbd, 0xad, 0x5b, 0x8b, 0x29, 0x06, 0x50, 0x53, 0x08, 0x01, 0xb1, 0x8e, 0xbf, 0xbf,
			0x5e, 0x8f, 0xab, 0x3c, 0x82, 0x87, 0x2a, 0x3e, 0x9b, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x32, 0xa3,
			0x49, 0x76, 0x5c, 0x5b, 0x35, 0x9a, 0x93, 0x3c, 0x6f, 0x3c, 0x63, 0x6d, 0xc0, 0x00
		};
		Send(response, 119);
		return;
	}

	// Check for a possible IP ban on this client.
	BAN_STATUS ipb = IPBanner::getSingleton().CalculateBanStatus(GetRemoteAddress());

	if(ipb != BAN_STATUS_NOT_BANNED)
		LOG_DETAIL("[AuthChallenge] Client %s is banned, refusing to continue.", GetRemoteIP().c_str());

	switch(ipb)
	{
		case BAN_STATUS_PERMANENT_BAN:
			SendChallengeError(CE_ACCOUNT_CLOSED);
			return;

		case BAN_STATUS_TIME_LEFT_ON_BAN:
			SendChallengeError(CE_ACCOUNT_FREEZED);
			return;

		default:
			break;
	}

	// Null-terminate the account string
	if(m_challenge.I_len >= 50) { Disconnect(); return; }
	m_challenge.I[m_challenge.I_len] = 0;

	// Clear the shitty hash (for server)
	string AccountName = (char*)&m_challenge.I;
	string::size_type i = AccountName.rfind("#");
	if(i != string::npos)
	{
		LOG_ERROR("# ACCOUNTNAME!");
		return;
		//AccountName.erase( i );
	}

	// Look up the account information
	LOG_DEBUG("[AuthChallenge] Account Name: \"%s\"", AccountName.c_str());

	m_account = AccountMgr::getSingleton().GetAccount(AccountName);
	if(m_account == 0)
	{
		LOG_DEBUG("[AuthChallenge] Invalid account.");

		// Non-existant account
		SendChallengeError(CE_NO_ACCOUNT);
		return;
	}

	LOG_DEBUG("[AuthChallenge] Account banned state = %u", m_account->Banned);

	// Check that the account isn't banned.
	if(m_account->Banned == 1)
	{
		SendChallengeError(CE_ACCOUNT_CLOSED);
		return;
	}
	else if(m_account->Banned > 0)
	{
		SendChallengeError(CE_ACCOUNT_FREEZED);
		return;
	}

	// update cached locale
	if(!m_account->forcedLocale)
	{
		char temp[4];
		temp[0] = m_challenge.country[3];
		temp[1] = m_challenge.country[2];
		temp[2] = m_challenge.country[1];
		temp[3] = m_challenge.country[0];

		*(uint32*)&m_account->Locale[0] = *(uint32*)temp;
	}

	//////////////////////////////////////////////// SRP6 Challenge ////////////////////////////////////////////////
	//
	//
	// First we will generate the Verifier value using the following formulas
	//
	// x = SHA1(s | SHA1(I | ":" | P))
	// v = g^x % N
	//
	// The SHA1(I | ":" | P) part for x we have in the account database, this is the encrypted password, reversed
	// N is a safe prime
	// g is the generator
	// | means concatenation in this contect
	//
	//

	Sha1Hash sha;
	sha.UpdateData(s.AsByteArray(), 32);
	sha.UpdateData(m_account->SrpHash, 20);
	sha.Finalize();

	BigNumber x;
	x.SetBinary(sha.GetDigest(), sha.GetLength());
	v = g.ModExp(x, N);

	// Next we generate b, and B which are the public and private values of the server
	//
	// b = random()
	// B = k*v + g^b % N
	//
	// in our case the multiplier parameters, k = 3

	b.SetRand(152);
	uint8 k = 3;

	BigNumber gmod = g.ModExp(b, N);
	B = ((v * k) + gmod) % N;
	ASSERT(gmod.GetNumBytes() <= 32);

	BigNumber unk;
	unk.SetRand(128);


	// Now we send B, g, N and s to the client as a challenge, asking the client for the proof
	sAuthLogonChallenge_S challenge;
	challenge.cmd = 0;
	challenge.error = 0;
	challenge.unk2 = CE_SUCCESS;
	memcpy(challenge.B, B.AsByteArray(), 32);
	challenge.g_len = 1;
	challenge.g = (g.AsByteArray())[ 0 ];
	challenge.N_len = 32;
	memcpy(challenge.N, N.AsByteArray(), 32);
	memcpy(challenge.s, s.AsByteArray(), 32);
	memcpy(challenge.unk3, unk.AsByteArray(), 16);
	challenge.unk4 = 0;

	Send(reinterpret_cast< uint8* >(&challenge), sizeof(sAuthLogonChallenge_S));
}
示例#25
0
//////////////////////////////////////////////////////////////////////////////////////////
/// This function handles CMSG_GAMEOBJECT_QUERY:
//////////////////////////////////////////////////////////////////////////////////////////
void WorldSession::HandleGameObjectQueryOpcode(WorldPacket& recv_data)
{
    CHECK_INWORLD_RETURN

    CHECK_PACKET_SIZE(recv_data, 12);
    WorldPacket data(SMSG_GAMEOBJECT_QUERY_RESPONSE, 900);

    uint32 entryID;
    uint64 guid;

    recv_data >> entryID;
    recv_data >> guid;

    LOG_DETAIL("WORLD: CMSG_GAMEOBJECT_QUERY '%u'", entryID);

    auto gameobject_info = GameObjectNameStorage.LookupEntry(entryID);
    if (gameobject_info == nullptr)
        return;

    LocalizedGameObjectName* lgn = (language > 0) ? sLocalizationMgr.GetLocalizedGameObjectName(entryID, language) : NULL;

    data << entryID;                // unique identifier of the GO template
    data << gameobject_info->type;           // type of the gameobject
    data << gameobject_info->display_id;      // displayid/modelid of the gameobject

    // Name of the gameobject
    if (lgn)
        data << lgn->Name;
    else
        data << gameobject_info->name;

    data << uint8(0);               // name2, always seems to be empty
    data << uint8(0);               // name3, always seems to be empty
    data << uint8(0);               // name4, always seems to be empty
    data << gameobject_info->category_name;  // Category string of the GO, like "attack", "pvp", "point", etc
    data << gameobject_info->cast_bar_text;  // text displayed when using the go, like "collecting", "summoning" etc
    data << gameobject_info->Unkstr;
    data << gameobject_info->parameter_0;     // spellfocus id, ex.: spell casted when interacting with the GO
    data << gameobject_info->parameter_1;
    data << gameobject_info->parameter_2;
    data << gameobject_info->parameter_3;
    data << gameobject_info->parameter_4;
    data << gameobject_info->parameter_5;
    data << gameobject_info->parameter_6;
    data << gameobject_info->parameter_7;
    data << gameobject_info->parameter_8;
    data << gameobject_info->parameter_9;
    data << gameobject_info->parameter_10;
    data << gameobject_info->parameter_11;
    data << gameobject_info->parameter_12;
    data << gameobject_info->parameter_13;
    data << gameobject_info->parameter_14;
    data << gameobject_info->parameter_15;
    data << gameobject_info->parameter_16;
    data << gameobject_info->parameter_17;
    data << gameobject_info->parameter_18;
    data << gameobject_info->parameter_19;
    data << gameobject_info->parameter_20;
    data << gameobject_info->parameter_21;
    data << gameobject_info->parameter_22;
    data << gameobject_info->parameter_23;
    data << float(gameobject_info->size);       // scaling of the GO

    // questitems that the go can contain
    for (uint32 i = 0; i < 6; ++i)
    {
        data << uint32(gameobject_info->QuestItems[i]);
    }

    SendPacket(&data);
}
示例#26
0
void AuthSocket::HandleReconnectChallenge()
{
	// No header
	if(readBuffer.GetContiguiousBytes() < 4)
		return;

	// Check the rest of the packet is complete.
	uint8* ReceiveBuffer = /*GetReadBuffer(0)*/(uint8*)readBuffer.GetBufferStart();
	uint16 full_size = *(uint16*)&ReceiveBuffer[2];
	LOG_DETAIL("[AuthChallenge] got header, body is %u bytes", full_size);

	if(readBuffer.GetSize() < (uint32)full_size + 4)
		return;

	// Copy the data into our cached challenge structure
	if((size_t)(full_size + 4) > sizeof(sAuthLogonChallenge_C))
	{
		Disconnect();
		return;
	}

	LOG_DEBUG("[AuthChallenge] got full packet.");

	memcpy(&m_challenge, ReceiveBuffer, full_size + 4);
	//RemoveReadBufferBytes(full_size + 4, false);
	readBuffer.Read(&m_challenge, full_size + 4);

	// Check client build.
	if(m_challenge.build > LogonServer::getSingleton().max_build ||
	        m_challenge.build < LogonServer::getSingleton().min_build)
	{
		SendChallengeError(CE_WRONG_BUILD_NUMBER);
		return;
	}

	// Check for a possible IP ban on this client.
	BAN_STATUS ipb = IPBanner::getSingleton().CalculateBanStatus(GetRemoteAddress());

	switch(ipb)
	{
		case BAN_STATUS_PERMANENT_BAN:
			SendChallengeError(CE_ACCOUNT_CLOSED);
			return;

		case BAN_STATUS_TIME_LEFT_ON_BAN:
			SendChallengeError(CE_ACCOUNT_FREEZED);
			return;

		default:
			break;
	}

	/* buffer overflow thing */
	if(m_challenge.I_len >= 50)
	{
		Disconnect();
		return;
	}

	// Null-terminate the account string
	m_challenge.I[m_challenge.I_len] = 0;

	// Clear the shitty hash (for server)
	/*	size_t i = 0;
		for( i = m_challenge.I_len; i >= 0; --i )
		{
			if( m_challenge.I[i] == '#' )
			{
				m_challenge.I[i] = '\0';
				break;
			}
		}*/

	// Look up the account information
	string AccountName = (char*)&m_challenge.I;
	LOG_DEBUG("[AuthChallenge] Account Name: \"%s\"", AccountName.c_str());

	m_account = AccountMgr::getSingleton().GetAccount(AccountName);
	if(m_account == 0)
	{
		LOG_DEBUG("[AuthChallenge] Invalid account.");

		// Non-existant account
		SendChallengeError(CE_NO_ACCOUNT);
		return;
	}

	LOG_DEBUG("[AuthChallenge] Account banned state = %u", m_account->Banned);

	// Check that the account isn't banned.
	if(m_account->Banned == 1)
	{
		SendChallengeError(CE_ACCOUNT_CLOSED);
		return;
	}
	else if(m_account->Banned > 0)
	{
		SendChallengeError(CE_ACCOUNT_FREEZED);
		return;
	}

	if(!m_account->SessionKey)
	{
		SendChallengeError(CE_SERVER_FULL);
		return;
	}

	/** burlex: this is pure speculation, I really have no idea what this does :p
	 * just guessed the md5 because it was 16 byte blocks.
	 */

	MD5_CTX ctx;
	MD5_Init(&ctx);
	MD5_Update(&ctx, m_account->SessionKey, 40);
	uint8 buffer[20];
	MD5_Final(buffer, &ctx);
	ByteBuffer buf;
	buf << uint16(2);
	buf.append(buffer, 20);
	buf << uint64(0);
	buf << uint64(0);
	Send(buf.contents(), 34);
}
示例#27
0
void WorldSession::HandleCastSpellOpcode(WorldPacket & recvPacket)
{
	CHECK_INWORLD_RETURN

	uint32 spellId;
	uint8 cn, unk; //Alice : Added to 3.0.2

	recvPacket >> cn >> spellId  >> unk;
	// check for spell id
	SpellEntry* spellInfo = dbcSpell.LookupEntryForced(spellId);

	if(!spellInfo)
	{
		LOG_DETAIL("ERROR: WORLD: unknown spell id %i", spellId);
		return;
	}

	if(!_player->isAlive() && _player->GetShapeShift() != FORM_SPIRITOFREDEMPTION && !(spellInfo->Attributes & ATTRIBUTES_DEAD_CASTABLE)) //They're dead, not in spirit of redemption and the spell can't be cast while dead.
		return;

	LOG_DETAIL("WORLD: got cast spell packet, spellId - %i (%s), data length = %i",
	           spellId, spellInfo->Name, recvPacket.size());

	// Cheat Detection only if player and not from an item
	// this could f**k up things but meh it's needed ALOT of the newbs are using WPE now
	// WPE allows them to mod the outgoing packet and basically choose what ever spell they want :(

	if(!GetPlayer()->HasSpell(spellId))
	{
		sCheatLog.writefromsession(this, "Cast spell %lu but doesn't have that spell.", spellId);
		LOG_DETAIL("WORLD: Spell isn't cast because player \'%s\' is cheating", GetPlayer()->GetName());
		return;
	}
	if(spellInfo->Attributes & ATTRIBUTES_PASSIVE)
	{
		sCheatLog.writefromsession(this, "Cast passive spell %lu.", spellId);
		LOG_DETAIL("WORLD: Spell isn't cast because player \'%s\' is cheating", GetPlayer()->GetName());
		return;
	}

	if(GetPlayer()->GetOnMeleeSpell() != spellId)
	{
		//autoshot 75
		if((spellInfo->AttributesExB & ATTRIBUTESEXB_ACTIVATE_AUTO_SHOT) /*spellInfo->Attributes == 327698*/)	// auto shot..
		{
			//sLog.outString( "HandleSpellCast: Auto Shot-type spell cast (id %u, name %s)" , spellInfo->Id , spellInfo->Name );
			Item* weapon = GetPlayer()->GetItemInterface()->GetInventoryItem(EQUIPMENT_SLOT_RANGED);
			if(!weapon)
				return;
			uint32 spellid;
			switch(weapon->GetProto()->SubClass)
			{
				case 2:			 // bows
				case 3:			 // guns
				case 18:		 // crossbow
					spellid = SPELL_RANGED_GENERAL;
					break;
				case 16:			// thrown
					spellid = SPELL_RANGED_THROW;
					break;
				case 19:			// wands
					spellid = SPELL_RANGED_WAND;
					break;
				default:
					spellid = 0;
					break;
			}

			if(!spellid)
				spellid = spellInfo->Id;

			if(!_player->m_onAutoShot)
			{
				_player->m_AutoShotTarget = _player->GetSelection();
				uint32 duration = _player->GetBaseAttackTime(RANGED);
				SpellCastTargets targets(recvPacket, GetPlayer()->GetGUID());
				if(!targets.m_unitTarget)
				{
					LOG_DEBUG("Cancelling auto-shot cast because targets.m_unitTarget is null!");
					return;
				}
				SpellEntry* sp = dbcSpell.LookupEntry(spellid);

				_player->m_AutoShotSpell = sp;
				_player->m_AutoShotDuration = duration;
				//This will fix fast clicks
				if(_player->m_AutoShotAttackTimer < 500)
					_player->m_AutoShotAttackTimer = 500;
				_player->m_onAutoShot = true;
			}

			return;
		}

		if(_player->m_currentSpell)
		{
			if(_player->m_currentSpell->getState() == SPELL_STATE_CASTING)
			{
				// cancel the existing channel spell, cast this one
				_player->m_currentSpell->cancel();
			}
			else
			{
				// send the error message
				_player->SendCastResult(spellInfo->Id, SPELL_FAILED_SPELL_IN_PROGRESS, cn, 0);
				return;
			}
		}

		SpellCastTargets targets(recvPacket, GetPlayer()->GetGUID());

		// some anticheat stuff
		if(spellInfo->self_cast_only)
		{
			if(targets.m_unitTarget && targets.m_unitTarget != _player->GetGUID())
			{
				// send the error message
				_player->SendCastResult(spellInfo->Id, SPELL_FAILED_BAD_TARGETS, cn, 0);
				return;
			}
		}

		Spell* spell = sSpellFactoryMgr.NewSpell(GetPlayer(), spellInfo, false, NULL);
		spell->extra_cast_number = cn;
		spell->prepare(&targets);
	}
}
示例#28
0
void Player::SendInitialLogonPackets()
{
	// Initial Packets... they seem to be re-sent on port.
	//m_session->OutPacket(SMSG_SET_REST_START_OBSOLETE, 4, &m_timeLogoff); // Seem to be unused by client

	StackWorldPacket<32> data(SMSG_BINDPOINTUPDATE);

	data << float(m_bind_pos_x);
	data << float(m_bind_pos_y);
	data << float(m_bind_pos_z);
	data << uint32(m_bind_mapid);
	data << uint32(m_bind_zoneid);

	m_session->SendPacket(&data);

	//Proficiencies
	SendSetProficiency(4, armor_proficiency);
	SendSetProficiency(2, weapon_proficiency);

	//Tutorial Flags
	data.Initialize(SMSG_TUTORIAL_FLAGS);

	for(int i = 0; i < 8; i++)
		data << uint32(m_Tutorials[i]);

	m_session->SendPacket(&data);

	smsg_TalentsInfo(false);
	smsg_InitialSpells();

	data.Initialize(SMSG_SEND_UNLEARN_SPELLS);
	data << uint32(0); // count, for(count) uint32;
	GetSession()->SendPacket(&data);

	SendInitialActions();
	smsg_InitialFactions();

	/* Some minor documentation about the time field
	// MOVE THIS DOCUMENTATION TO THE WIKI

	minute's = 0x0000003F                  00000000000000000000000000111111
	hour's   = 0x000007C0                  00000000000000000000011111000000
	weekdays = 0x00003800                  00000000000000000011100000000000
	days     = 0x000FC000                  00000000000011111100000000000000
	months   = 0x00F00000                  00000000111100000000000000000000
	years    = 0x1F000000                  00011111000000000000000000000000
	unk	     = 0xE0000000                  11100000000000000000000000000000
	*/

	data.Initialize(SMSG_LOGIN_SETTIMESPEED);

	time_t minutes = sWorld.GetGameTime() / 60;
	time_t hours = minutes / 60;
	minutes %= 60;
	time_t gameTime = 0;

	// TODO: Add stuff to handle these variables

	time_t basetime = UNIXTIME;
	uint32 DayOfTheWeek;
	if(localtime(&basetime)->tm_wday == 0)
		DayOfTheWeek = 6;
	else
		DayOfTheWeek = localtime(&basetime)->tm_wday - 1;
	uint32 DayOfTheMonth = localtime(&basetime)->tm_mday - 1;
	uint32 CurrentMonth = localtime(&basetime)->tm_mon;
	uint32 CurrentYear = localtime(&basetime)->tm_year - 100;

#define MINUTE_BITMASK      0x0000003F
#define HOUR_BITMASK        0x000007C0
#define WEEKDAY_BITMASK     0x00003800
#define DAY_BITMASK         0x000FC000
#define MONTH_BITMASK       0x00F00000
#define YEAR_BITMASK        0x1F000000
#define UNK_BITMASK         0xE0000000

#define MINUTE_SHIFTMASK    0
#define HOUR_SHIFTMASK      6
#define WEEKDAY_SHIFTMASK   11
#define DAY_SHIFTMASK       14
#define MONTH_SHIFTMASK     20
#define YEAR_SHIFTMASK      24
#define UNK_SHIFTMASK       29

	gameTime = ((minutes << MINUTE_SHIFTMASK) & MINUTE_BITMASK);
	gameTime |= ((hours << HOUR_SHIFTMASK) & HOUR_BITMASK);
	gameTime |= ((DayOfTheWeek << WEEKDAY_SHIFTMASK) & WEEKDAY_BITMASK);
	gameTime |= ((DayOfTheMonth << DAY_SHIFTMASK) & DAY_BITMASK);
	gameTime |= ((CurrentMonth << MONTH_SHIFTMASK) & MONTH_BITMASK);
	gameTime |= ((CurrentYear << YEAR_SHIFTMASK) & YEAR_BITMASK);

	data << uint32(gameTime);
	data << float(0.0166666669777748f);    // Normal Game Speed
	data << uint32(0);   // 3.1.2

	m_session->SendPacket(&data);

	// cebernic for speedhack bug
	m_lastRunSpeed = 0;
	UpdateSpeed();

	WorldPacket ArenaSettings(SMSG_UPDATE_WORLD_STATE, 16);

	ArenaSettings << uint32(0xC77);
	ArenaSettings << uint32(sWorld.Arena_Progress);
	ArenaSettings << uint32(0xF3D);
	ArenaSettings << uint32(sWorld.Arena_Season);

	m_session->SendPacket(&ArenaSettings);

	LOG_DETAIL("WORLD: Sent initial logon packets for %s.", GetName());
}
示例#29
0
void SpellFactoryMgr::LoadSpellAreas()
{
    mSpellAreaMap.clear();
    mSpellAreaForQuestMap.clear();
    mSpellAreaForActiveQuestMap.clear();
    mSpellAreaForQuestEndMap.clear();
    mSpellAreaForAuraMap.clear();

    //                                                  0     1         2              3               4           5          6        7       8
    QueryResult* result = WorldDatabase.Query("SELECT spell, area, quest_start, quest_start_active, quest_end, aura_spell, racemask, gender, autocast FROM spell_area");

    if (!result)
    {
        LOG_DETAIL("Loaded 0 spell area requirements. DB table `spell_area` is empty.");
        return;
    }

    uint32 pCount = 0;
    do
    {
        Field* fields = result->Fetch();

        uint32 spell = fields[0].GetUInt32();
        SpellArea spellArea;
        spellArea.spellId = spell;
        spellArea.areaId = fields[1].GetUInt32();
        spellArea.questStart = fields[2].GetUInt32();
        spellArea.questStartCanActive = fields[3].GetBool();
        spellArea.questEnd = fields[4].GetUInt32();
        spellArea.auraSpell = fields[5].GetInt32();
        spellArea.raceMask = fields[6].GetUInt32();
        spellArea.gender = Gender(fields[7].GetUInt8());
        spellArea.autocast = fields[8].GetBool();

        {
            bool ok = true;
            SpellAreaMapBounds sa_bounds = GetSpellAreaMapBounds(spellArea.spellId);
            for (SpellAreaMap::const_iterator itr = sa_bounds.first; itr != sa_bounds.second; ++itr)
            {
                if (spellArea.spellId != itr->second.spellId)
                    continue;
                if (spellArea.areaId != itr->second.areaId)
                    continue;
                if (spellArea.questStart != itr->second.questStart)
                    continue;
                if (spellArea.auraSpell != itr->second.auraSpell)
                    continue;
                if ((spellArea.raceMask & itr->second.raceMask) == 0)
                    continue;
                if (spellArea.gender != itr->second.gender)
                    continue;

                // duplicate by requirements
                ok = false;
                break;
            }

            if (!ok)
            {
                LOG_ERROR("Spell %u listed in `spell_area` already listed with similar requirements.", spell);
                continue;
            }
        }

        /*
        if (spellArea.areaId && !AreaTriggerStorage.LookupEntry(spellArea.areaId))
        {
        printf("Spell %u listed in `spell_area` have wrong area (%u) requirement \n", spell, spellArea.areaId);
        continue;
        }
        */

        if (spellArea.questStart && !sMySQLStore.getQuestProperties(spellArea.questStart))
        {
            LOG_ERROR("Spell %u listed in `spell_area` have wrong start quest (%u) requirement.", spell, spellArea.questStart);
            continue;
        }

        if (spellArea.questEnd)
        {
            if (!sMySQLStore.getQuestProperties(spellArea.questEnd))
            {
                LOG_ERROR("Spell %u listed in `spell_area` have wrong end quest (%u) requirement.", spell, spellArea.questEnd);
                continue;
            }

            if (spellArea.questEnd == spellArea.questStart && !spellArea.questStartCanActive)
            {
                LOG_ERROR("Spell %u listed in `spell_area` have quest (%u) requirement for start and end in same time.", spell, spellArea.questEnd);
                continue;
            }
        }

        if (spellArea.auraSpell)
        {
            SpellInfo const* spellInfo = sSpellCustomizations.GetSpellInfo(abs(spellArea.auraSpell));
            if (!spellInfo)
            {
                LOG_ERROR("Spell %u listed in `spell_area` have wrong aura spell (%u) requirement.", spell, abs(spellArea.auraSpell));
                continue;
            }

            if (uint32(abs(spellArea.auraSpell)) == spellArea.spellId)
            {
                LogDebugFlag(LF_SPELL, "Spell %u listed in `spell_area` have aura spell (%u) requirement for itself.", spell, abs(spellArea.auraSpell));
                continue;
            }

            // not allow autocast chains by auraSpell field (but allow use as alternative if not present)
            if (spellArea.autocast && spellArea.auraSpell > 0)
            {
                bool chain = false;
                SpellAreaForAuraMapBounds saBound = GetSpellAreaForAuraMapBounds(spellArea.spellId);
                for (SpellAreaForAuraMap::const_iterator itr = saBound.first; itr != saBound.second; ++itr)
                {
                    if (itr->second->autocast && itr->second->auraSpell > 0)
                    {
                        chain = true;
                        break;
                    }
                }

                if (chain)
                {
                    LogDebugFlag(LF_SPELL, "Spell %u listed in `spell_area` have aura spell (%u) requirement that itself autocast from aura.", spell, spellArea.auraSpell);
                    continue;
                }

                SpellAreaMapBounds saBound2 = GetSpellAreaMapBounds(spellArea.auraSpell);
                for (SpellAreaMap::const_iterator itr2 = saBound2.first; itr2 != saBound2.second; ++itr2)
                {
                    if (itr2->second.autocast && itr2->second.auraSpell > 0)
                    {
                        chain = true;
                        break;
                    }
                }

                if (chain)
                {
                    LogDebugFlag(LF_SPELL, "Spell %u listed in `spell_area` have aura spell (%u) requirement that itself autocast from aura.", spell, spellArea.auraSpell);
                    continue;
                }
            }
        }

        if (spellArea.raceMask && (spellArea.raceMask & RACEMASK_ALL_PLAYABLE) == 0)
        {
            LOG_ERROR("Spell %u listed in `spell_area` have wrong race mask (%u) requirement.", spell, spellArea.raceMask);
            continue;
        }

        if (spellArea.gender != GENDER_NONE && spellArea.gender != GENDER_FEMALE && spellArea.gender != GENDER_MALE)
        {
            LOG_ERROR("Spell %u listed in `spell_area` have wrong gender (%u) requirement.", spell, spellArea.gender);
            continue;
        }

        SpellArea const* sa = &mSpellAreaMap.insert(SpellAreaMap::value_type(spell, spellArea))->second;

        // for search by current zone/subzone at zone/subzone change
        if (spellArea.areaId)
            mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(spellArea.areaId, sa));

        // for search at quest start/reward
        if (spellArea.questStart)
        {
            if (spellArea.questStartCanActive)
                mSpellAreaForActiveQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
            else
                mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa));
        }

        // for search at quest start/reward
        if (spellArea.questEnd)
            mSpellAreaForQuestEndMap.insert(SpellAreaForQuestMap::value_type(spellArea.questEnd, sa));

        // for search at aura apply
        if (spellArea.auraSpell)
            mSpellAreaForAuraMap.insert(SpellAreaForAuraMap::value_type(abs(spellArea.auraSpell), sa));

        ++pCount;
    } while (result->NextRow());
    delete result;

    LOG_DETAIL("Loaded %u spell area requirements.", pCount);
}
示例#30
0
void AddonMgr::SendAddonInfoPacket(WorldPacket* source, uint32 pos, WorldSession* m_session)
{
	WorldPacket returnpacket;
	returnpacket.Initialize(SMSG_ADDON_INFO);	// SMSG_ADDON_INFO

	uint32 realsize;
	uLongf rsize;

	try
	{
		*source >> realsize;
	}
	catch(ByteBuffer::error &)
	{
		LOG_DEBUG("Warning: Incomplete auth session sent.");
		return;
	}

	rsize = realsize;
	size_t position = source->rpos();

	ByteBuffer unpacked;
	unpacked.resize(realsize);

	if((source->size() - position) < 4 || realsize == 0)
	{
		// we shouldn't get here.. but just in case this will stop any crash here.
		LOG_DEBUG("Warning: Incomplete auth session sent.");
		return;
	}

	int32 result = uncompress((uint8*)unpacked.contents(), &rsize, (uint8*)(*source).contents() + position, (uLong)((*source).size() - position));

	if(result != Z_OK)
	{
		LOG_ERROR("Decompression of addon section of CMSG_AUTH_SESSION failed.");
		return;
	}

	LOG_DETAIL("Decompression of addon section of CMSG_AUTH_SESSION succeeded.");

	uint8 Enable; // based on the parsed files from retool
	uint32 crc;
	uint32 unknown;

	std::string name;

	uint32 addoncount;
	unpacked >> addoncount;

	uint8 unk;
	uint8 unk1;
	uint8 unk2;
	for(uint32 i = 0; i < addoncount; ++i)
	{
		if(unpacked.rpos() >= unpacked.size())
			break;

		unpacked >> name;
		unpacked >> Enable;
		unpacked >> crc;
		unpacked >> unknown;

		// Hacky fix, Yea I know its a hacky fix I will make a proper handler one's I got the crc crap
		/*		if (crc != 0x4C1C776D) // CRC of public key version 2.0.1
					returnpacket.append(PublicKey,264); // part of the hacky fix
				else
					returnpacket << uint8(0x02) << uint8(0x01) << uint8(0x00) << uint32(0) << uint8(0);*/
		/*if(!AppendPublicKey(returnpacket, name, crc))
			returnpacket << uint8(1) << uint8(0) << uint8(0);*/

		unk = (Enable ? 2 : 1);
		returnpacket << unk;
		unk1 = (Enable ? 1 : 0);
		returnpacket << unk1;
		if(unk1)
		{
			if(crc != 0x4C1C776D)
			{
				returnpacket << uint8(1);
				returnpacket.append(PublicKey, 264);
			}
			else
				returnpacket << uint8(0);

			returnpacket << uint32(0);
		}

		unk2 = (Enable ? 0 : 1);
		returnpacket << unk2;
		if(unk2)
			returnpacket << uint8(0);
	}

	/*unknown 4 bytes at the end of the packet. Stays 0 for me. Tried custom addons, deleting, faulty etc. It stays 0.
	*/
	returnpacket << uint32(0); //Some additional count for additional records, but we won't send them.

	m_session->SendPacket(&returnpacket);
}