diff options
| -rwxr-xr-x | src/server/game/Entities/Player/Player.cpp | 10 | ||||
| -rwxr-xr-x | src/server/game/Entities/Player/Player.h | 24 | ||||
| -rwxr-xr-x | src/server/game/Entities/Player/SocialMgr.h | 10 | ||||
| -rwxr-xr-x | src/server/game/Server/Protocol/Handlers/MiscHandler.cpp | 4 | ||||
| -rw-r--r-- | src/server/game/Server/Protocol/Handlers/ReferAFriendHandler.cpp | 80 | ||||
| -rwxr-xr-x | src/server/game/Server/Protocol/Opcodes.cpp | 6 | ||||
| -rwxr-xr-x | src/server/game/Server/WorldSession.h | 4 |
7 files changed, 127 insertions, 11 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 6b032f40e8a..54429cdac7d 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3061,6 +3061,16 @@ void Player::GiveLevel(uint8 level) GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL); + // Refer-A-Friend + if (GetSession()->GetRecruiterId()) + if (level < sWorld.getConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL)) { + if (level % 2 == 0) { + m_grantableLevels++; + + if (!HasByteFlag(PLAYER_FIELD_BYTES, 1, 0x01)) + SetByteFlag(PLAYER_FIELD_BYTES, 1, 0x01); + } + sScriptMgr->OnPlayerLevelChanged(this, oldLevel); } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 87ceff75ccb..3b7f381060f 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -866,6 +866,24 @@ enum CurrencyItems ITEM_ARENA_POINTS_ID = 43307 }; +enum ReferAFriendError +{ + ERR_REFER_A_FRIEND_NONE = 0x00, + ERR_REFER_A_FRIEND_NOT_REFERRED_BY = 0x01, + ERR_REFER_A_FRIEND_TARGET_TOO_HIGH = 0x02, + ERR_REFER_A_FRIEND_INSUFFICIENT_GRANTABLE_LEVELS = 0x03, + ERR_REFER_A_FRIEND_TOO_FAR = 0x04, + ERR_REFER_A_FRIEND_DIFFERENT_FACTION = 0x05, + ERR_REFER_A_FRIEND_NOT_NOW = 0x06, + ERR_REFER_A_FRIEND_GRANT_LEVEL_MAX_I = 0x07, + ERR_REFER_A_FRIEND_NO_TARGET = 0x08, + ERR_REFER_A_FRIEND_NOT_IN_GROUP = 0x09, + ERR_REFER_A_FRIEND_SUMMON_LEVEL_MAX_I = 0x0A, + ERR_REFER_A_FRIEND_SUMMON_COOLDOWN = 0x0B, + ERR_REFER_A_FRIEND_INSUF_EXPAN_LVL = 0x0C, + ERR_REFER_A_FRIEND_SUMMON_OFFLINE_S = 0x0D +}; + class PlayerTaxi { public: @@ -1989,7 +2007,8 @@ class Player : public Unit, public GridObject<Player> bool isHonorOrXPTarget(Unit* pVictim); bool GetsRecruitAFriendBonus(bool forXP); - uint8 GetGrantableLevels() { return GetByteValue(PLAYER_FIELD_BYTES, 1); } + uint8 GetGrantableLevels() { return m_grantableLevels; } + void SetGrantableLevels(uint8 val) { m_grantableLevels = val; } ReputationMgr& GetReputationMgr() { return m_reputationMgr; } ReputationMgr const& GetReputationMgr() const { return m_reputationMgr; } @@ -2693,6 +2712,9 @@ class Player : public Unit, public GridObject<Player> bool canSeeAlways(WorldObject const* obj) const; bool isAlwaysDetectableFor(WorldObject const* seer) const; + + uint8 m_grantableLevels; + private: // internal common parts for CanStore/StoreItem functions InventoryResult _CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemPosCountVec& dest, ItemTemplate const *pProto, uint32& count, bool swap, Item *pSrcItem) const; diff --git a/src/server/game/Entities/Player/SocialMgr.h b/src/server/game/Entities/Player/SocialMgr.h index 2b54df70da3..af1f9c1d43c 100755 --- a/src/server/game/Entities/Player/SocialMgr.h +++ b/src/server/game/Entities/Player/SocialMgr.h @@ -30,11 +30,11 @@ class WorldPacket; enum FriendStatus { - FRIEND_STATUS_OFFLINE = 0, - FRIEND_STATUS_ONLINE = 1, - FRIEND_STATUS_AFK = 2, - FRIEND_STATUS_UNK3 = 3, - FRIEND_STATUS_DND = 4 + FRIEND_STATUS_OFFLINE = 0x00, + FRIEND_STATUS_ONLINE = 0x01, + FRIEND_STATUS_AFK = 0x02, + FRIEND_STATUS_DND = 0x04, + FRIEND_STATUS_RAF = 0x08 }; enum SocialFlag diff --git a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp index 74c51a4f726..e6ff961d216 100755 --- a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp @@ -494,12 +494,12 @@ void WorldSession::HandleSetSelectionOpcode(WorldPacket & recv_data) uint64 guid; recv_data >> guid; - _player->SetSelection(guid); - // update reputation list if need Unit* unit = ObjectAccessor::GetUnit(*_player, guid); if (!unit) return; + + _player->SetSelectionGuid(guid); if (FactionTemplateEntry const* factionTemplateEntry = sFactionTemplateStore.LookupEntry(unit->getFaction())) _player->GetReputationMgr().SetVisible(factionTemplateEntry); diff --git a/src/server/game/Server/Protocol/Handlers/ReferAFriendHandler.cpp b/src/server/game/Server/Protocol/Handlers/ReferAFriendHandler.cpp new file mode 100644 index 00000000000..2307cfed624 --- /dev/null +++ b/src/server/game/Server/Protocol/Handlers/ReferAFriendHandler.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2011 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +void WorldSession::HandleGrantLevel(WorldPacket& recv_data) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GRANT_LEVEL"); + + uint64 guid; + recv_data.readPackGUID(guid); + + Player *target = sObjectMgr.GetPlayer(guid); + + // check cheating + uint8 levels = _player->GetGrantableLevels(); + uint8 error = 0; + if (!target) + error = ERR_REFER_A_FRIEND_NO_TARGET; + else if (levels == 0) + error = ERR_REFER_A_FRIEND_INSUFFICIENT_GRANTABLE_LEVELS; + else if (GetSession()->GetRecruiterId() != target->GetSession()->GetAccountId()) + error = ERR_REFER_A_FRIEND_NOT_REFERRED_BY; + else if (target->GetTeamId() != _player->GetTeamId()) + error = ERR_REFER_A_FRIEND_DIFFERENT_FACTION; + else if (target->GetLevel() >= _player->GetLevel()) + error = ERR_REFER_A_FRIEND_TARGET_TOO_HIGH; + else if (target->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL)) + error = ERR_REFER_A_FRIEND_GRANT_LEVEL_MAX_I; + else if (target->GetGroup() != _player->GetGroup()) + error = ERR_REFER_A_FRIEND_NOT_IN_GROUP; + + if (error) { + WorldPacket data(SMSG_REFER_A_FRIEND_ERROR, 24); + data << uint32(error); + if (error == ERR_REFER_A_FRIEND_NOT_IN_GROUP) + data << target->GetName(); + + GetSession()->SendPacket(&data); + return; + } + + WorldPacket data(SMSG_PROPOSE_LEVEL_GRANT, 8); + data << _player->GetPackGUID(); + target->GetSession()->SendPacket(&data); +} + +void WorldSession::HandleAcceptGrantLevel(WorldPacket& recv_data) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_ACCEPT_LEVEL_GRANT"); + + uint64 guid; + recv_data.readPackGUID(guid); + + Player *other = sObjectMgr.GetPlayer(guid); + if (!(other && other->GetSession())) + return; + + if (_player->GetSession()->GetAccountId() != other->GetSession()->GetRecruiterId()) + return; + + if (other->GetGrantableLevels()) + other->SetGrantableLevels(other->GetGrantableLevels() - 1); + else + return; + + _player->GiveLevel(_player->getLevel() + 1); +} diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 235f349e1ea..14381491874 100755 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1063,7 +1063,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x40A*/ { "MSG_QUERY_GUILD_BANK_TEXT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryGuildBankTabText }, /*0x40B*/ { "CMSG_SET_GUILD_BANK_TEXT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetGuildBankTabText }, /*0x40C*/ { "CMSG_SET_GRANTABLE_LEVELS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x40D*/ { "CMSG_GRANT_LEVEL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, + /*0x40D*/ { "CMSG_GRANT_LEVEL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGrantLevel }, /*0x40E*/ { "CMSG_REFER_A_FRIEND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x40F*/ { "MSG_GM_CHANGE_ARENA_RATING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, /*0x410*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleChannelDeclineInvite }, @@ -1082,13 +1082,13 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x41D*/ { "SMSG_SERVER_BUCK_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x41E*/ { "SMSG_SEND_UNLEARN_SPELLS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x41F*/ { "SMSG_PROPOSE_LEVEL_GRANT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, - /*0x420*/ { "CMSG_ACCEPT_LEVEL_GRANT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, + /*0x420*/ { "CMSG_ACCEPT_LEVEL_GRANT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptGrantLevel }, /*0x421*/ { "SMSG_REFER_A_FRIEND_FAILURE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x422*/ { "SMSG_SPLINE_MOVE_SET_FLYING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x423*/ { "SMSG_SPLINE_MOVE_UNSET_FLYING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x424*/ { "SMSG_SUMMON_CANCEL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x425*/ { "CMSG_CHANGE_PERSONAL_ARENA_RATING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL }, - /*0x426*/ { "CMSG_ALTER_APPEARANCE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAlterAppearance }, + /*0x426*/ { "CMSG_ALTER_APPEARANCE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAlterAppearance }, /*0x427*/ { "SMSG_ENABLE_BARBER_SHOP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x428*/ { "SMSG_BARBER_SHOP_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide }, /*0x429*/ { "CMSG_CALENDAR_GET_CALENDAR", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetCalendar }, diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index ef1b87d37da..1d6f69aac51 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -858,6 +858,10 @@ class WorldSession void HandleQueryGuildBankTabText(WorldPacket& recv_data); void HandleSetGuildBankTabText(WorldPacket& recv_data); + // Refer-a-Friend + void HandleGrantLevel(WorldPacket& recv_data); + void HandleAcceptGrantLevel(WorldPacket& recv_data); + // Calendar void HandleCalendarGetCalendar(WorldPacket& recv_data); void HandleCalendarGetEvent(WorldPacket& recv_data); |
