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); }
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 ); }
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); }
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( ); } }
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); }
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 ); }
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); }
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."); }
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; } }
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); }
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); } }
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(); }
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 ); }
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); }