mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-28 09:33:52 +00:00
Add Tier 6 commands: party/raid management
- Uninvite/kick: /uninvite, /kick <player name> to remove player from party/raid - Leave party: /leave, /leaveparty to leave current group - Main tank: /maintank, /mt to set target as main tank (uses raid marker index 0) - Main assist: /mainassist, /ma to set target as main assist (uses raid marker index 1) - Clear markers: /clearmaintank, /clearmainassist to remove designations - Raid info: /raidinfo to display raid lockouts and saved instances Added opcodes: - CMSG_REQUEST_RAID_INFO (0x2CD) for requesting raid lockout info - SMSG_RAID_INSTANCE_INFO (0x2CC) for receiving raid info response New packet builders: - GroupUninvitePacket for removing players from group - GroupDisbandPacket for leaving party (with logging) - RaidTargetUpdatePacket for setting raid markers (main tank/assist) - RequestRaidInfoPacket for querying raid lockouts All commands include proper validation and user feedback.
This commit is contained in:
parent
627c2fe0f6
commit
d5b734a591
6 changed files with 246 additions and 11 deletions
|
|
@ -261,6 +261,15 @@ public:
|
|||
std::string getLastWhisperSender() const { return lastWhisperSender_; }
|
||||
void setLastWhisperSender(const std::string& name) { lastWhisperSender_ = name; }
|
||||
|
||||
// Party/Raid management
|
||||
void uninvitePlayer(const std::string& playerName);
|
||||
void leaveParty();
|
||||
void setMainTank(uint64_t targetGuid);
|
||||
void setMainAssist(uint64_t targetGuid);
|
||||
void clearMainTank();
|
||||
void clearMainAssist();
|
||||
void requestRaidInfo();
|
||||
|
||||
// ---- Phase 1: Name queries ----
|
||||
void queryPlayerName(uint64_t guid);
|
||||
void queryCreatureInfo(uint32_t entry, uint64_t guid);
|
||||
|
|
|
|||
|
|
@ -175,6 +175,8 @@ enum class Opcode : uint16_t {
|
|||
SMSG_GROUP_LIST = 0x07D,
|
||||
SMSG_PARTY_COMMAND_RESULT = 0x07E,
|
||||
MSG_RAID_TARGET_UPDATE = 0x321,
|
||||
CMSG_REQUEST_RAID_INFO = 0x2CD,
|
||||
SMSG_RAID_INSTANCE_INFO = 0x2CC,
|
||||
|
||||
// ---- Phase 5: Loot ----
|
||||
CMSG_AUTOSTORE_LOOT_ITEM = 0x108,
|
||||
|
|
|
|||
|
|
@ -884,6 +884,39 @@ public:
|
|||
static network::Packet build();
|
||||
};
|
||||
|
||||
// ============================================================
|
||||
// Party/Raid Management
|
||||
// ============================================================
|
||||
|
||||
/** CMSG_GROUP_UNINVITE_GUID packet builder */
|
||||
class GroupUninvitePacket {
|
||||
public:
|
||||
static network::Packet build(const std::string& playerName);
|
||||
};
|
||||
|
||||
/** CMSG_GROUP_DISBAND packet builder */
|
||||
class GroupDisbandPacket {
|
||||
public:
|
||||
static network::Packet build();
|
||||
};
|
||||
|
||||
/** MSG_RAID_TARGET_UPDATE packet builder */
|
||||
class RaidTargetUpdatePacket {
|
||||
public:
|
||||
/**
|
||||
* Build raid target marker update packet
|
||||
* @param targetIndex 0-7 for raid icons, 0 = MainTank, 1 = MainAssist
|
||||
* @param targetGuid GUID to mark, or 0 to clear
|
||||
*/
|
||||
static network::Packet build(uint8_t targetIndex, uint64_t targetGuid);
|
||||
};
|
||||
|
||||
/** CMSG_REQUEST_RAID_INFO packet builder */
|
||||
class RequestRaidInfoPacket {
|
||||
public:
|
||||
static network::Packet build();
|
||||
};
|
||||
|
||||
// ============================================================
|
||||
// Random Roll
|
||||
// ============================================================
|
||||
|
|
@ -1315,12 +1348,6 @@ public:
|
|||
static network::Packet build();
|
||||
};
|
||||
|
||||
/** CMSG_GROUP_DISBAND (leave party) packet builder */
|
||||
class GroupDisbandPacket {
|
||||
public:
|
||||
static network::Packet build();
|
||||
};
|
||||
|
||||
/** SMSG_GROUP_LIST parser */
|
||||
class GroupListParser {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -2116,6 +2116,109 @@ void GameHandler::replyToLastWhisper(const std::string& message) {
|
|||
LOG_INFO("Replied to ", lastWhisperSender_, ": ", message);
|
||||
}
|
||||
|
||||
void GameHandler::uninvitePlayer(const std::string& playerName) {
|
||||
if (state != WorldState::IN_WORLD || !socket) {
|
||||
LOG_WARNING("Cannot uninvite player: not in world or not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
if (playerName.empty()) {
|
||||
addSystemChatMessage("You must specify a player name to uninvite.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto packet = GroupUninvitePacket::build(playerName);
|
||||
socket->send(packet);
|
||||
addSystemChatMessage("Removed " + playerName + " from the group.");
|
||||
LOG_INFO("Uninvited player: ", playerName);
|
||||
}
|
||||
|
||||
void GameHandler::leaveParty() {
|
||||
if (state != WorldState::IN_WORLD || !socket) {
|
||||
LOG_WARNING("Cannot leave party: not in world or not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
auto packet = GroupDisbandPacket::build();
|
||||
socket->send(packet);
|
||||
addSystemChatMessage("You have left the group.");
|
||||
LOG_INFO("Left party/raid");
|
||||
}
|
||||
|
||||
void GameHandler::setMainTank(uint64_t targetGuid) {
|
||||
if (state != WorldState::IN_WORLD || !socket) {
|
||||
LOG_WARNING("Cannot set main tank: not in world or not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
if (targetGuid == 0) {
|
||||
addSystemChatMessage("You must have a target selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Main tank uses index 0
|
||||
auto packet = RaidTargetUpdatePacket::build(0, targetGuid);
|
||||
socket->send(packet);
|
||||
addSystemChatMessage("Main tank set.");
|
||||
LOG_INFO("Set main tank: 0x", std::hex, targetGuid, std::dec);
|
||||
}
|
||||
|
||||
void GameHandler::setMainAssist(uint64_t targetGuid) {
|
||||
if (state != WorldState::IN_WORLD || !socket) {
|
||||
LOG_WARNING("Cannot set main assist: not in world or not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
if (targetGuid == 0) {
|
||||
addSystemChatMessage("You must have a target selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Main assist uses index 1
|
||||
auto packet = RaidTargetUpdatePacket::build(1, targetGuid);
|
||||
socket->send(packet);
|
||||
addSystemChatMessage("Main assist set.");
|
||||
LOG_INFO("Set main assist: 0x", std::hex, targetGuid, std::dec);
|
||||
}
|
||||
|
||||
void GameHandler::clearMainTank() {
|
||||
if (state != WorldState::IN_WORLD || !socket) {
|
||||
LOG_WARNING("Cannot clear main tank: not in world or not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear main tank by setting GUID to 0
|
||||
auto packet = RaidTargetUpdatePacket::build(0, 0);
|
||||
socket->send(packet);
|
||||
addSystemChatMessage("Main tank cleared.");
|
||||
LOG_INFO("Cleared main tank");
|
||||
}
|
||||
|
||||
void GameHandler::clearMainAssist() {
|
||||
if (state != WorldState::IN_WORLD || !socket) {
|
||||
LOG_WARNING("Cannot clear main assist: not in world or not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear main assist by setting GUID to 0
|
||||
auto packet = RaidTargetUpdatePacket::build(1, 0);
|
||||
socket->send(packet);
|
||||
addSystemChatMessage("Main assist cleared.");
|
||||
LOG_INFO("Cleared main assist");
|
||||
}
|
||||
|
||||
void GameHandler::requestRaidInfo() {
|
||||
if (state != WorldState::IN_WORLD || !socket) {
|
||||
LOG_WARNING("Cannot request raid info: not in world or not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
auto packet = RequestRaidInfoPacket::build();
|
||||
socket->send(packet);
|
||||
addSystemChatMessage("Requesting raid lockout information...");
|
||||
LOG_INFO("Requested raid info");
|
||||
}
|
||||
|
||||
void GameHandler::releaseSpirit() {
|
||||
if (!playerDead_) return;
|
||||
if (socket && state == WorldState::IN_WORLD) {
|
||||
|
|
|
|||
|
|
@ -1421,6 +1421,37 @@ network::Packet DuelCancelPacket::build() {
|
|||
return packet;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Party/Raid Management
|
||||
// ============================================================
|
||||
|
||||
network::Packet GroupUninvitePacket::build(const std::string& playerName) {
|
||||
network::Packet packet(static_cast<uint16_t>(Opcode::CMSG_GROUP_UNINVITE_GUID));
|
||||
packet.writeString(playerName);
|
||||
LOG_DEBUG("Built CMSG_GROUP_UNINVITE_GUID for player: ", playerName);
|
||||
return packet;
|
||||
}
|
||||
|
||||
network::Packet GroupDisbandPacket::build() {
|
||||
network::Packet packet(static_cast<uint16_t>(Opcode::CMSG_GROUP_DISBAND));
|
||||
LOG_DEBUG("Built CMSG_GROUP_DISBAND");
|
||||
return packet;
|
||||
}
|
||||
|
||||
network::Packet RaidTargetUpdatePacket::build(uint8_t targetIndex, uint64_t targetGuid) {
|
||||
network::Packet packet(static_cast<uint16_t>(Opcode::MSG_RAID_TARGET_UPDATE));
|
||||
packet.writeUInt8(targetIndex);
|
||||
packet.writeUInt64(targetGuid);
|
||||
LOG_DEBUG("Built MSG_RAID_TARGET_UPDATE, index: ", (uint32_t)targetIndex, ", guid: 0x", std::hex, targetGuid, std::dec);
|
||||
return packet;
|
||||
}
|
||||
|
||||
network::Packet RequestRaidInfoPacket::build() {
|
||||
network::Packet packet(static_cast<uint16_t>(Opcode::CMSG_REQUEST_RAID_INFO));
|
||||
LOG_DEBUG("Built CMSG_REQUEST_RAID_INFO");
|
||||
return packet;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Random Roll
|
||||
// ============================================================
|
||||
|
|
@ -2092,11 +2123,6 @@ network::Packet GroupDeclinePacket::build() {
|
|||
return packet;
|
||||
}
|
||||
|
||||
network::Packet GroupDisbandPacket::build() {
|
||||
network::Packet packet(static_cast<uint16_t>(Opcode::CMSG_GROUP_DISBAND));
|
||||
return packet;
|
||||
}
|
||||
|
||||
bool GroupListParser::parse(network::Packet& packet, GroupListData& data) {
|
||||
data.groupType = packet.readUInt8();
|
||||
data.subGroup = packet.readUInt8();
|
||||
|
|
|
|||
|
|
@ -1330,6 +1330,74 @@ void GameScreen::sendChatMessage(game::GameHandler& gameHandler) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Party/Raid management commands
|
||||
if (cmdLower == "uninvite" || cmdLower == "kick") {
|
||||
if (spacePos != std::string::npos) {
|
||||
std::string playerName = command.substr(spacePos + 1);
|
||||
gameHandler.uninvitePlayer(playerName);
|
||||
} else {
|
||||
game::MessageChatData msg;
|
||||
msg.type = game::ChatType::SYSTEM;
|
||||
msg.language = game::ChatLanguage::UNIVERSAL;
|
||||
msg.message = "Usage: /uninvite <player name>";
|
||||
gameHandler.addLocalChatMessage(msg);
|
||||
}
|
||||
chatInputBuffer[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmdLower == "leave" || cmdLower == "leaveparty") {
|
||||
gameHandler.leaveParty();
|
||||
chatInputBuffer[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmdLower == "maintank" || cmdLower == "mt") {
|
||||
if (gameHandler.hasTarget()) {
|
||||
gameHandler.setMainTank(gameHandler.getTargetGuid());
|
||||
} else {
|
||||
game::MessageChatData msg;
|
||||
msg.type = game::ChatType::SYSTEM;
|
||||
msg.language = game::ChatLanguage::UNIVERSAL;
|
||||
msg.message = "You must target a player to set as main tank.";
|
||||
gameHandler.addLocalChatMessage(msg);
|
||||
}
|
||||
chatInputBuffer[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmdLower == "mainassist" || cmdLower == "ma") {
|
||||
if (gameHandler.hasTarget()) {
|
||||
gameHandler.setMainAssist(gameHandler.getTargetGuid());
|
||||
} else {
|
||||
game::MessageChatData msg;
|
||||
msg.type = game::ChatType::SYSTEM;
|
||||
msg.language = game::ChatLanguage::UNIVERSAL;
|
||||
msg.message = "You must target a player to set as main assist.";
|
||||
gameHandler.addLocalChatMessage(msg);
|
||||
}
|
||||
chatInputBuffer[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmdLower == "clearmaintank") {
|
||||
gameHandler.clearMainTank();
|
||||
chatInputBuffer[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmdLower == "clearmainassist") {
|
||||
gameHandler.clearMainAssist();
|
||||
chatInputBuffer[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmdLower == "raidinfo") {
|
||||
gameHandler.requestRaidInfo();
|
||||
chatInputBuffer[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
// Chat channel slash commands
|
||||
bool isChannelCommand = false;
|
||||
if (cmdLower == "s" || cmdLower == "say") {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue