aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/Player.cpp36
-rw-r--r--src/server/game/Entities/Player/Player.h12
-rw-r--r--src/server/game/Server/Packets/MiscPackets.h2
-rw-r--r--src/server/game/Server/Packets/SpellPackets.cpp20
-rw-r--r--src/server/game/Server/Packets/SpellPackets.h28
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp6
6 files changed, 71 insertions, 33 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 3ba4f662426..c70317873be 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -6203,29 +6203,20 @@ int16 Player::GetSkillTempBonusValue(uint32 skill) const
void Player::SendActionButtons(uint32 state) const
{
- WorldPacket data(SMSG_ACTION_BUTTONS, 1+(MAX_ACTION_BUTTONS*4));
- /*
- state can be 0, 1, 2
- 0 - Sends initial action buttons, client does not validate if we have the spell or not
- 1 - Used used after spec swaps, client validates if a spell is known.
- 2 - Clears the action bars client sided. This is sent during spec swap before unlearning and before sending the new buttons
- */
- if (state != 2)
+ WorldPackets::Spell::UpdateActionButtons packet;
+
+ for (uint8 button = 0; button < MAX_ACTION_BUTTONS; ++button)
{
- for (uint8 button = 0; button < MAX_ACTION_BUTTONS; ++button)
- {
- ActionButtonList::const_iterator itr = m_actionButtons.find(button);
- if (itr != m_actionButtons.end() && itr->second.uState != ACTIONBUTTON_DELETED)
- data << uint32(itr->second.packedData);
- else
- data << uint32(0);
- }
+ ActionButtonList::const_iterator itr = m_actionButtons.find(button);
+ if (itr != m_actionButtons.end() && itr->second.uState != ACTIONBUTTON_DELETED)
+ packet.ActionButtons[button] = uint32(itr->second.packedData);
+ else
+ packet.ActionButtons[button] = 0;
}
- else
- data.resize(MAX_ACTION_BUTTONS * 4); // insert crap, client doesnt even parse this for state == 2
- data << uint8(state);
- GetSession()->SendPacket(&data);
+ packet.Reason = state;
+
+ GetSession()->SendPacket(packet.Write());
TC_LOG_INFO("network", "Action Buttons for '%s' group '%u' Sent", GetGUID().ToString().c_str(), GetActiveTalentGroup());
}
@@ -23017,9 +23008,8 @@ void Player::SendInitialPacketsBeforeAddToMap()
SendKnownSpells();
- data.Initialize(SMSG_SEND_UNLEARN_SPELLS, 4);
- data << uint32(0); // count, for (count) uint32;
- GetSession()->SendPacket(&data);
+ WorldPackets::Spell::SendUnlearnSpells packet;
+ GetSession()->SendPacket(packet.Write());
SendInitialActionButtons();
m_reputationMgr->SendInitialReputations();
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 39eace840f3..1dd993e5b5f 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -328,15 +328,15 @@ enum ReputationSource
REPUTATION_SOURCE_SPELL
};
-#define ACTION_BUTTON_ACTION(X) (uint32(X) & 0x00FFFFFF)
-#define ACTION_BUTTON_TYPE(X) ((uint32(X) & 0xFF000000) >> 24)
-#define MAX_ACTION_BUTTON_ACTION_VALUE (0x00FFFFFF+1)
+#define ACTION_BUTTON_ACTION(X) (uint64(X) & 0x00000000FFFFFFFF)
+#define ACTION_BUTTON_TYPE(X) ((uint64(X) & 0xFFFFFFFF00000000) >> 32)
+#define MAX_ACTION_BUTTON_ACTION_VALUE (0xFFFFFFFF)
struct ActionButton
{
ActionButton() : packedData(0), uState(ACTIONBUTTON_NEW) { }
- uint32 packedData;
+ uint64 packedData;
ActionButtonUpdateState uState;
// helpers
@@ -344,7 +344,7 @@ struct ActionButton
uint32 GetAction() const { return ACTION_BUTTON_ACTION(packedData); }
void SetActionAndType(uint32 action, ActionButtonType type)
{
- uint32 newData = action | (uint32(type) << 24);
+ uint64 newData = uint64(action) | (uint64(type) << 32);
if (newData != packedData || uState == ACTIONBUTTON_DELETED)
{
packedData = newData;
@@ -354,7 +354,7 @@ struct ActionButton
}
};
-#define MAX_ACTION_BUTTONS 144 //checked in 3.2.0
+#define MAX_ACTION_BUTTONS 132
typedef std::map<uint8, ActionButton> ActionButtonList;
diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h
index 520b9acafc1..86f2f4c5eb4 100644
--- a/src/server/game/Server/Packets/MiscPackets.h
+++ b/src/server/game/Server/Packets/MiscPackets.h
@@ -68,7 +68,7 @@ namespace WorldPackets
class TutorialFlags : public ServerPacket
{
public:
- TutorialFlags() : ServerPacket(SMSG_WORLD_STATE_UI_TIMER_UPDATE, 32) { }
+ TutorialFlags() : ServerPacket(SMSG_TUTORIAL_FLAGS, 32) { }
WorldPacket const* Write() override;
diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp
index 57c8bcb3e3d..601f1f3e5a8 100644
--- a/src/server/game/Server/Packets/SpellPackets.cpp
+++ b/src/server/game/Server/Packets/SpellPackets.cpp
@@ -44,3 +44,23 @@ WorldPacket const* WorldPackets::Spell::SendKnownSpells::Write()
return &_worldPacket;
}
+
+WorldPacket const* WorldPackets::Spell::UpdateActionButtons::Write()
+{
+ for (uint32 i = 0; i < MAX_ACTION_BUTTONS; ++i)
+ _worldPacket << ActionButtons[i];
+
+ _worldPacket << Reason;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Spell::SendUnlearnSpells::Write()
+{
+ _worldPacket << uint32(Spells.size());
+ for (uint32 i = 0; i < Spells.size(); ++i)
+ _worldPacket << Spells[0];
+
+ return &_worldPacket;
+}
+
diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h
index dde50e46759..2b4e4c3c146 100644
--- a/src/server/game/Server/Packets/SpellPackets.h
+++ b/src/server/game/Server/Packets/SpellPackets.h
@@ -19,6 +19,7 @@
#define SpellPackets_h__
#include "Packet.h"
+#include "Player.h"
namespace WorldPackets
{
@@ -53,6 +54,33 @@ namespace WorldPackets
bool InitialLogin = false;
std::vector<uint32> KnownSpells;
};
+
+ class UpdateActionButtons final : public ServerPacket
+ {
+ public:
+ UpdateActionButtons() : ServerPacket(SMSG_ACTION_BUTTONS, MAX_ACTION_BUTTONS*8+1) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 ActionButtons[MAX_ACTION_BUTTONS];
+ uint8 Reason = 0;
+ /*
+ Reason can be 0, 1, 2
+ 0 - Sends initial action buttons, client does not validate if we have the spell or not
+ 1 - Used used after spec swaps, client validates if a spell is known.
+ 2 - Clears the action bars client sided. This is sent during spec swap before unlearning and before sending the new buttons
+ */
+ };
+
+ class SendUnlearnSpells final : public ServerPacket
+ {
+ public:
+ SendUnlearnSpells() : ServerPacket(SMSG_SEND_UNLEARN_SPELLS, 4) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<uint32> Spells;
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index c7b3b549468..d8ea1f3861d 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -697,7 +697,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_RESTRICTED_WARNING, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_DELETED, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_EARNED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACTION_BUTTONS, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACTION_BUTTONS, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACTIVATETAXIREPLY, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADDON_INFO, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADD_RUNE_POWER, STATUS_UNHANDLED);
@@ -1252,7 +1252,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RWHOIS, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SELL_ITEM, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_MAIL_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_UNLEARN_SPELLS, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_UNLEARN_SPELLS, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVERTIME, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_FIRST_ACHIEVEMENT, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_INFO_RESPONSE, STATUS_UNHANDLED);
@@ -1367,7 +1367,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_CINEMATIC, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_MOVIE, STATUS_UNHANDLED);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TURN_IN_PETITION_RESULTS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TUTORIAL_FLAGS, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TUTORIAL_FLAGS, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNDELETE_CHARACTER_RESPONSE, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNDELETE_COOLDOWN_STATUS_RESPONSE, STATUS_NEVER);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNIT_HEALTH_FREQUENT, STATUS_UNHANDLED);