[Shared Tasks] Cleanup shared task request and remove (#2341)

Functionally nothing should change in this patch. This refactors a lot
of formatting and code duplication in requests and member removals.

The long SharedTaskMessage namespace and its constants were contributing
to a lot of formatting that was difficult to read. These were shortened
since they're not all shared task specific anyway (though they should
probably just be moved to string_ids.h with other eqstrs now)

Shared task requests were refactored a little to remove an unnecessary
function that filled potential members. The separate functions used for
/taskquit and /taskremove were also combined into a single function to
remove a member while preserving live message differences.
This commit is contained in:
hg 2022-07-30 21:36:04 -04:00 committed by GitHub
parent 8a962e09f6
commit d243cbf8a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 220 additions and 419 deletions

View File

@ -52,21 +52,22 @@ void SharedTask::SetDbSharedTask(const SharedTasksRepository::SharedTasks &m_db_
SharedTask::m_db_shared_task = m_db_shared_task;
}
SharedTaskRequestCharacters SharedTask::GetRequestCharacters(Database &db, uint32_t requested_character_id)
SharedTaskRequest SharedTask::GetRequestCharacters(Database &db, uint32_t requested_character_id)
{
SharedTaskRequestCharacters request{};
// todo: group/raid refactors to check online members without querying
SharedTaskRequest request{};
request.group_type = SharedTaskRequestGroupType::Group;
request.characters = CharacterDataRepository::GetWhere(
auto characters = CharacterDataRepository::GetWhere(
db, fmt::format(
"id IN (select charid from group_id where groupid = (select groupid from group_id where charid = {}))",
requested_character_id
)
);
if (request.characters.empty()) {
if (characters.empty()) {
request.group_type = SharedTaskRequestGroupType::Raid;
request.characters = CharacterDataRepository::GetWhere(
characters = CharacterDataRepository::GetWhere(
db, fmt::format(
"id IN (select charid from raid_members where raidid = (select raidid from raid_members where charid = {}))",
requested_character_id
@ -74,10 +75,10 @@ SharedTaskRequestCharacters SharedTask::GetRequestCharacters(Database &db, uint3
);
}
if (request.characters.empty()) // solo request
if (characters.empty()) // solo request
{
request.group_type = SharedTaskRequestGroupType::Solo;
request.characters = CharacterDataRepository::GetWhere(
characters = CharacterDataRepository::GetWhere(
db, fmt::format(
"id = {} LIMIT 1",
requested_character_id
@ -85,12 +86,24 @@ SharedTaskRequestCharacters SharedTask::GetRequestCharacters(Database &db, uint3
);
}
request.leader_id = requested_character_id;
request.lowest_level = std::numeric_limits<uint8_t>::max();
request.highest_level = 0;
for (const auto &character: request.characters) {
request.members.reserve(characters.size());
for (const auto& character: characters)
{
request.lowest_level = std::min(request.lowest_level, character.level);
request.highest_level = std::max(request.highest_level, character.level);
request.character_ids.emplace_back(character.id); // convenience
SharedTaskMember member = {};
member.character_id = character.id;
member.character_name = character.name;
if (character.id == requested_character_id)
{
member.is_leader = true;
}
request.members.emplace_back(member);
}
return request;

View File

@ -16,7 +16,7 @@
#define ServerOP_SharedTaskAddPlayer 0x0301 // bidirectional. /taskaddplayer request zone -> world. success world -> zone
#define ServerOP_SharedTaskMakeLeader 0x0302 // zone -> world -> zone
#define ServerOP_SharedTaskRemovePlayer 0x0303 // zone -> world -> zone
#define ServerOP_SharedTaskAttemptRemove 0x0304 // zone -> world. Player trying to delete task
#define ServerOP_SharedTaskQuit 0x0304 // zone -> world. Player trying to delete task
#define ServerOP_SharedTaskUpdate 0x0305 // zone -> world. Client sending task update to world. Relayed world -> zone on confirmation
#define ServerOP_SharedTaskMemberlist 0x0306 // world -> zone. Send shared task memberlist
#define ServerOP_SharedTaskRequestMemberlist 0x0307 // zone -> world. Send shared task memberlist (zone in initial for now, could change)
@ -55,11 +55,11 @@ struct ServerSharedTaskInvitePlayer_Struct {
char inviter_name[64];
};
// ServerOP_SharedTaskAttemptRemove
// ServerOP_SharedTaskQuit
// gets re-used when sent back to clients
struct ServerSharedTaskAttemptRemove_Struct {
struct ServerSharedTaskQuit_Struct {
uint32 requested_character_id;
uint32 requested_task_id;
uint32 task_id;
bool remove_from_db;
};
@ -77,12 +77,13 @@ struct SharedTaskMember {
};
// used in shared task requests to validate group/raid members
struct SharedTaskRequestCharacters {
struct SharedTaskRequest {
int lowest_level;
int highest_level;
uint32_t leader_id;
SharedTaskRequestGroupType group_type;
std::vector<uint32_t> character_ids;
std::vector<CharacterDataRepository::CharacterData> characters;
std::vector<SharedTaskMember> members;
};
// ServerOP_SharedTaskMemberlist
@ -174,7 +175,7 @@ struct ServerSharedTaskLock_Struct {
class SharedTask {
public:
// used in both zone and world validation
static SharedTaskRequestCharacters GetRequestCharacters(Database& db, uint32_t requested_character_id);
static SharedTaskRequest GetRequestCharacters(Database& db, uint32_t requested_character_id);
void AddCharacterToMemberHistory(uint32_t character_id);
SharedTaskMember FindMemberFromCharacterID(uint32_t character_id) const;

View File

@ -344,15 +344,15 @@ namespace Tasks {
}
}
namespace SharedTaskMessage {
constexpr uint16 TASK_ASSIGN_WAIT_REPLAY_TIMER = 8017; // This task can not be assigned to you because you must wait %1d:%2h:%3m before you can do another task of this type.
namespace TaskStr {
constexpr uint16 ASSIGN_REPLAY_TIMER = 8017; // This task can not be assigned to you because you must wait %1d:%2h:%3m before you can do another task of this type.
constexpr uint16 COULD_NOT_USE_COMMAND = 8272; // You could not use this command because you are not currently assigned to a shared task.
constexpr uint16 AVG_LVL_LOW = 8553; // You can not be assigned this shared task because your party's average level is too low.
constexpr uint16 AVG_LVL_HIGH = 8889; // You can not be assigned this shared task because your party's average level is too high.
constexpr uint16 LVL_TOO_LOW = 8553; // You can not be assigned this shared task because your party's average level is too low.
constexpr uint16 LVL_TOO_HIGH = 8889; // You can not be assigned this shared task because your party's average level is too high.
constexpr uint16 LVL_SPREAD_HIGH = 8890; // You can not be assigned this shared task because your party's level spread is too high.
constexpr uint16 PARTY_EXCEED_MAX_PLAYER = 8891; // You can not be assigned this shared task because your party exceeds the maximum allowed number of players.
constexpr uint16 MAX_PLAYERS = 8891; // You can not be assigned this shared task because your party exceeds the maximum allowed number of players.
constexpr uint16 LEADER_NOT_MEET_REQUIREMENTS = 8892; // You can not be assigned this shared task because the leader does not meet the shared task requirements.
constexpr uint16 SHARED_TASK_NOT_MEET_MIN_NUM_PLAYER = 8895; // You can not be assigned this shared task because your party does not contain the minimum required number of players.
constexpr uint16 MIN_PLAYERS = 8895; // You can not be assigned this shared task because your party does not contain the minimum required number of players.
constexpr uint16 WILL_REMOVE_ZONE_TWO_MIN_RAID_NOT_MIN_NUM_PLAYER = 8908; // %1 will be removed from their zone in two minutes because your raid does not meet the minimum requirement of qualified players.
constexpr uint16 WILL_REMOVE_ZONE_TWO_MIN_GROUP_NOT_MIN_NUM_PLAYER = 8909; // %1 will be removed from their zone in two minutes because your group does not meet the minimum requirement of qualified players.
constexpr uint16 WILL_REMOVE_AREA_TWO_MIN_RAID_NOT_MIN_NUM_PLAYER = 8910; // %1 will be removed from their area in two minutes because your raid does not meet the minimum requirement of qualified players.
@ -363,12 +363,12 @@ namespace SharedTaskMessage {
constexpr uint16 HAS_REMOVED_AREA_TWO_MIN_GROUP_NOT_MIN_NUM_PLAYER = 8915; // %1 has been removed from their area because your group does not meet the minimum requirement of qualified players.
constexpr uint16 SEND_INVITE_TO = 8916; // Sending a shared task invitation to %1.
constexpr uint16 COULD_NOT_BE_INVITED = 8917; // %1 could not be invited to join you.
constexpr uint16 YOU_ARE_NOT_LEADER_COMMAND_ISSUE = 8919; // You are not the shared task leader. Only %1 can issue this command.
constexpr uint16 NOT_LEADER = 8919; // You are not the shared task leader. Only %1 can issue this command.
constexpr uint16 SWAP_SENDING_INVITATION_TO = 8920; // Sending an invitation to: %1. They must accept in order to swap party members.
constexpr uint16 SWAP_ACCEPTED_OFFER = 8921; // %1 has accepted your offer to join your shared task. Swapping %1 for %2.
constexpr uint16 IS_NOT_MEMBER = 8922; // %1 is not a member of this shared task.
constexpr uint16 NOT_ALLOW_PLAYER_REMOVE = 8923; // The shared task is not allowing players to be removed from it at this time.
constexpr uint16 PLAYER_HAS_BEEN_REMOVED = 8924; // %1 has been removed from your shared task, '%2'.
constexpr uint16 PLAYER_REMOVED = 8924; // %1 has been removed from your shared task, '%2'.
constexpr uint16 TRANSFER_LEADERSHIP_NOT_ONLINE = 8925; // %1 is not currently online. You can only transfer leadership to an online member of the shared task.
constexpr uint16 MADE_LEADER = 8926; // %1 has been made the leader for this shared task.
constexpr uint16 YOU_MADE_LEADER = 8927; // You have been made the leader of this shared task.
@ -376,43 +376,43 @@ namespace SharedTaskMessage {
constexpr uint16 MEMBERS_PRINT = 8929; // Shared Task Members: %1
constexpr uint16 PLAYER_ACCEPTED_OFFER_JOIN = 8930; // %1 has accepted your offer to join your shared task.
constexpr uint16 PLAYER_HAS_BEEN_ADDED = 8931; // %1 has been added to your shared task, '%2'.
constexpr uint16 ACCEPTED_OFFER_TO_JOIN_BUT_COULD_NOT = 8932; // %1 accepted your offer to join your shared task but could not.
constexpr uint16 COULD_NOT_JOIN = 8932; // %1 accepted your offer to join your shared task but could not.
constexpr uint16 PLAYER_DECLINED_OFFER = 8933; // %1 has declined your offer to join your shared task.
constexpr uint16 PLAYER_HAS_ASKED_YOU_TO_JOIN = 8934; // %1 has asked you to join the shared task '%2'. Would you like to join?
constexpr uint16 NO_REQUEST_BECAUSE_HAVE_ONE = 8935; // You may not request a shared task because you already have one.
constexpr uint16 NO_REQUEST_BECAUSE_RAID_HAS_ONE = 8936; // You may not request a shared task because someone in your raid, %1, already has one.
constexpr uint16 NO_REQUEST_BECAUSE_GROUP_HAS_ONE = 8937; // You may not request a shared task because someone in your group, %1, already has one.
constexpr uint16 YOU_DO_NOT_MEET_REQ_AVAILABLE = 8938; // You do not meet the requirements for any available shared tasks.
constexpr uint16 REQUEST_HAVE = 8935; // You may not request a shared task because you already have one.
constexpr uint16 REQUEST_RAID_HAS = 8936; // You may not request a shared task because someone in your raid, %1, already has one.
constexpr uint16 REQUEST_GROUP_HAS = 8937; // You may not request a shared task because someone in your group, %1, already has one.
constexpr uint16 NOT_MEET_REQ = 8938; // You do not meet the requirements for any available shared tasks.
constexpr uint16 YOUR_RAID_DOES_NOT_MEET_REQ = 8939; // Your raid does not meet the requirements for any available shared tasks.
constexpr uint16 YOUR_GROUP_DOES_NOT_MEET_REQ = 8940; // Your group does not meet the requirements for any available shared tasks.
constexpr uint16 YOUR_GROUP__RAID_DOES_NOT_MEET_REQ = 8941; // You can not be assigned this shared task because the raid or group does not meet the shared task requirements.
constexpr uint16 YOU_NO_LONGER_MEMBER = 8942; // You are no longer a member of the shared task.
constexpr uint16 NO_LONGER_MEMBER = 8942; // You are no longer a member of the shared task.
constexpr uint16 YOU_MAY_NOT_REQUEST_EXPANSION = 8943; // You may not request this shared task because you do not have the required expansion.
constexpr uint16 PLAYER_MAY_NOT_REQUEST_EXPANSION = 8944; // You may not request this shared task because %1 does not have the required expansion.
constexpr uint16 TWO_MIN_REQ_TASK_TERMINATED = 8945; // If your party does not meet the requirements in two minutes, the shared task will be terminated.
constexpr uint16 YOU_MUST_WAIT_REPLAY_TIMER = 8946; // You may not request this shared task because you must wait %1d:%2h:%3m before you can do another task of this type.
constexpr uint16 PLAYER_MUST_WAIT_REPLAY_TIMER = 8947; // You may not request this shared task because %1 must wait %2d:%3h:%4m before they can do another task of this type.
constexpr uint16 YOU_REPLAY_TIMER = 8946; // You may not request this shared task because you must wait %1d:%2h:%3m before you can do another task of this type.
constexpr uint16 PLAYER_REPLAY_TIMER = 8947; // You may not request this shared task because %1 must wait %2d:%3h:%4m before they can do another task of this type.
constexpr uint16 PLAYER_NOW_LEADER = 8948; // %1 is now the leader of your shared task, '%2'.
constexpr uint16 HAS_ENDED = 8951; // Your shared task, '%1', has ended.
constexpr uint16 YOU_ALREADY_LEADER = 8952; // You are already the leader of the shared task.
constexpr uint16 TASK_NO_LONGER_ACTIVE = 8953; // Your shared task, '%1', is no longer active.
constexpr uint16 YOU_HAVE_BEEN_ADDED_TO_TASK = 8954; // You have been added to the shared task '%1'.
constexpr uint16 YOU_ARE_NOW_LEADER = 8955; // You are now the leader of your shared task, '%1'.
constexpr uint16 YOU_HAVE_BEEN_REMOVED = 8956; // You have been removed from the shared task '%1'.
constexpr uint16 YOU_ARE_NO_LONGER_A_MEMBER = 8960; // You are no longer a member of the shared task, '%1'.
constexpr uint16 YOUR_TASK_NOW_LOCKED = 8961; // Your shared task is now locked. You may no longer add or remove players.
constexpr uint16 TASK_NOT_ALLOWING_PLAYERS_AT_TIME = 8962; // The shared task is not allowing players to be added at this time.
constexpr uint16 PLAYER_NOT_ONLINE_TO_ADD = 8963; // %1 is not currently online. A player needs to be online to be added to a shared task.
constexpr uint16 CANT_ADD_PLAYER_ALREADY_MEMBER = 8964; // You can not add %1 because they are already a member of this shared task.
constexpr uint16 CANT_ADD_PLAYER_ALREADY_ASSIGNED = 8965; // You can not add %1 because they are already assigned to another shared task.
constexpr uint16 PLAYER_ALREADY_OUTSTANDING_INVITATION_THIS = 8966; // %1 already has an outstanding invitation to join this shared task.
constexpr uint16 PLAYER_ALREADY_OUTSTANDING_ANOTHER = 8967; // %1 already has an outstanding invitation to join another shared task. Players may only have one invitation outstanding.
constexpr uint16 CANT_ADD_PLAYER_MAX_PLAYERS = 8968; // You can not add another player since you currently have the maximum number of players allowed (%1) in this shared task.
constexpr uint16 CANT_ADD_PLAYER_MAX_LEVEL_SPREAD = 8969; // You can not add this player because you would exceed the maximum level spread (%1) for this shared task.
constexpr uint16 CANT_ADD_PLAYER_MAX_AVERAGE_LEVEL = 8970; // You can not add this player because you would exceed the maximum average level for this shared task.
constexpr uint16 CANT_ADD_PLAYER_FALL_MIN_AVG_LEVEL = 8971; // You can not add this player because you would fall below the minimum average level for this shared task.
constexpr uint16 YOU_REMOVED = 8956; // You have been removed from the shared task '%1'.
constexpr uint16 NO_LONGER_MEMBER_TITLE = 8960; // You are no longer a member of the shared task, '%1'.
constexpr uint16 TASK_LOCKED = 8961; // Your shared task is now locked. You may no longer add or remove players.
constexpr uint16 NOT_ALLOWING_PLAYERS = 8962; // The shared task is not allowing players to be added at this time.
constexpr uint16 PLAYER_NOT_ONLINE = 8963; // %1 is not currently online. A player needs to be online to be added to a shared task.
constexpr uint16 PLAYER_ALREADY_MEMBER = 8964; // You can not add %1 because they are already a member of this shared task.
constexpr uint16 PLAYER_ALREADY_ASSIGNED = 8965; // You can not add %1 because they are already assigned to another shared task.
constexpr uint16 PLAYER_INVITED = 8966; // %1 already has an outstanding invitation to join this shared task.
constexpr uint16 PLAYER_INVITED_OTHER = 8967; // %1 already has an outstanding invitation to join another shared task. Players may only have one invitation outstanding.
constexpr uint16 CANT_ADD_MAX_PLAYERS = 8968; // You can not add another player since you currently have the maximum number of players allowed (%1) in this shared task.
constexpr uint16 CANT_ADD_LVL_SPREAD = 8969; // You can not add this player because you would exceed the maximum level spread (%1) for this shared task.
constexpr uint16 CANT_ADD_MAX_LEVEL = 8970; // You can not add this player because you would exceed the maximum average level for this shared task.
constexpr uint16 CANT_ADD_MIN_LEVEL = 8971; // You can not add this player because you would fall below the minimum average level for this shared task.
constexpr uint16 PLAYER_DOES_NOT_OWN_EXPANSION = 8972; // %1 does not own the expansion needed for this shared task.
constexpr uint16 CANT_ADD_PLAYER_PARTY_FILTER_REQ_FOR_TASK = 8973; // You can not add this player because your party would no longer meet the filter requirements for this shared task.
constexpr uint16 CANT_ADD_FILTER_REQS = 8973; // You can not add this player because your party would no longer meet the filter requirements for this shared task.
constexpr uint16 CANT_ADD_PLAYER_ONE_OF_GROUP_RAID_HAS_TASK = 8977; // You can not add %1 because they or one of their group or raid members is in another shared task.
constexpr uint16 CANT_JOIN_GROUP_ACTIVE_TASK = 8978; // You can not join that group because you have an active shared task.
constexpr uint16 CANT_ADD_PLAYER_REPLAY_TIMER = 8979; // You may not add %1 because they must wait %2d:%3h:%4m before they can do another task of this type.
@ -423,40 +423,48 @@ namespace SharedTaskMessage {
constexpr uint16 PLAYER_CANT_ADD_RAID_BECAUSE_DIFF_TASK = 8984; // %1 can not be added to the raid because they are in a different shared task.
constexpr uint16 YOU_CANT_ADD_RAID_BECAUSE_DIFF_TASK = 8985; // You can not be added to the raid because you are in a different shared task.
constexpr uint16 REPLAY_TIMER_REMAINING = 8987; // '%1' replay timer: %2d:%3h:%4m remaining.
constexpr uint16 YOU_NO_CURRENT_REPLAY_TIMERS = 8989; // You do not currently have any task replay timers.
constexpr uint16 NO_REPLAY_TIMERS = 8989; // You do not currently have any task replay timers.
constexpr uint16 SURE_QUIT_TASK = 8995; // Are you sure you want to quit the task '%1'?
constexpr uint16 SURE_REMOVE_SELF_FROM_TASK = 8996; // Are you sure you want to remove yourself from the shared task '%1'
constexpr uint16 TASK_ASSIGN_WAIT_REQUEST_TIMER = 14506; // This task can not be assigned to you because you must wait %1d:%2h:%3m before you can request another task of this type.
constexpr uint16 ASSIGN_REQUEST_TIMER = 14506; // This task can not be assigned to you because you must wait %1d:%2h:%3m before you can request another task of this type.
constexpr uint16 REQUEST_TIMER_REMAINING = 14507; // '%1' request timer: %2d:%3h:%4m remaining.
constexpr uint16 YOU_MUST_WAIT_REQUEST_TIMER = 14508; // You may not request this shared task because you must wait %1d:%2h:%3m before you can request another task of this type.
constexpr uint16 YOU_REQUEST_TIMER = 14508; // You may not request this shared task because you must wait %1d:%2h:%3m before you can request another task of this type.
constexpr uint16 RECEIVED_REQUEST_TIMER = 14509; // You have received a request timer for '%1': %2d:%3h:%4m remaining.
constexpr uint16 RECEIVED_REPLAY_TIMER = 14510; // You have received a replay timer for '%1': %2d:%3h:%4m remaining.
constexpr uint16 PLAYER_MUST_WAIT_REQUEST_TIMER = 14511; // You may not request this shared task because %1 must wait %2d:%3h:%4m before they can request another task of this type.
constexpr uint16 PLAYER_REQUEST_TIMER = 14511; // You may not request this shared task because %1 must wait %2d:%3h:%4m before they can request another task of this type.
constexpr uint16 CANT_ADD_PLAYER_REQUEST_TIMER = 14512; // You may not add %1 because they must wait %2d:%3h:%4m before they can request another task of this type.
// for eqstrs not in current emu clients (some are also used by non-shared tasks)
constexpr auto GetEQStr(uint16 eqstr_id)
constexpr auto Get(uint16 eqstr_id)
{
switch (eqstr_id)
{
case SharedTaskMessage::COULD_NOT_USE_COMMAND:
case TaskStr::LVL_TOO_LOW:
return "You can not be assigned this shared task because your party's minimum level is too low.";
case TaskStr::LVL_TOO_HIGH:
return "You can not be assigned this shared task because your party's maximum level is too high.";
case TaskStr::COULD_NOT_USE_COMMAND:
return "You could not use this command because you are not currently assigned to a shared task.";
case SharedTaskMessage::TASK_ASSIGN_WAIT_REQUEST_TIMER:
case TaskStr::CANT_ADD_MAX_LEVEL:
return "You can not add this player because their level exceeds the maximum level limit for this shared task.";
case TaskStr::CANT_ADD_MIN_LEVEL:
return "You can not add this player because their level is below the minimum required level for this shared task.";
case TaskStr::ASSIGN_REQUEST_TIMER:
return "This task can not be assigned to you because you must wait {}d:{}h:{}m before you can request another task of this type.";
case SharedTaskMessage::REQUEST_TIMER_REMAINING:
case TaskStr::REQUEST_TIMER_REMAINING:
return "'{}' request timer: {}d:{}h:{}m remaining.";
case SharedTaskMessage::YOU_MUST_WAIT_REQUEST_TIMER:
case TaskStr::YOU_REQUEST_TIMER:
return "You may not request this shared task because you must wait {}d:{}h:{}m before you can request another task of this type.";
case SharedTaskMessage::RECEIVED_REQUEST_TIMER:
case TaskStr::RECEIVED_REQUEST_TIMER:
return "You have received a request timer for '{}': {}d:{}h:{}m remaining.";
case SharedTaskMessage::RECEIVED_REPLAY_TIMER:
case TaskStr::RECEIVED_REPLAY_TIMER:
return "You have received a replay timer for '{}': {}d:{}h:{}m remaining.";
case SharedTaskMessage::PLAYER_MUST_WAIT_REQUEST_TIMER:
case TaskStr::PLAYER_REQUEST_TIMER:
return "You may not request this shared task because {} must wait {}d:{}h:{}m before they can request another task of this type.";
case SharedTaskMessage::CANT_ADD_PLAYER_REQUEST_TIMER:
case TaskStr::CANT_ADD_PLAYER_REQUEST_TIMER:
return "You may not add {} because they must wait {}d:{}h:{}m before they can request another task of this type.";
default:
LogTasks("[GetEQStr] Unhandled eqstr id [{}]", eqstr_id);
LogTasks("[TaskStr::Get] Unhandled eqstr id [{}]", eqstr_id);
break;
}
return "Unknown EQStr";

View File

@ -34,30 +34,6 @@ SharedTaskManager *SharedTaskManager::SetContentDatabase(Database *db)
return this;
}
std::vector<SharedTaskMember> SharedTaskManager::GetRequestMembers(
uint32 requestor_character_id,
const std::vector<CharacterDataRepository::CharacterData> &characters
)
{
std::vector<SharedTaskMember> request_members = {};
request_members.reserve(characters.size());
for (const auto &character : characters) {
SharedTaskMember member = {};
member.character_id = character.id;
member.character_name = character.name;
// if the solo/raid/group member is a leader, make sure we tag it as such
if (character.id == requestor_character_id) {
member.is_leader = true;
}
request_members.emplace_back(member);
}
return request_members;
}
void SharedTaskManager::AttemptSharedTaskCreation(
uint32 requested_task_id,
uint32 requested_character_id,
@ -74,25 +50,16 @@ void SharedTaskManager::AttemptSharedTaskCreation(
}
// shared task validation
// todo: this should be online group/raid members only (avoid queries)
auto request = SharedTask::GetRequestCharacters(*m_database, requested_character_id);
if (!CanRequestSharedTask(task.id, requested_character_id, request)) {
if (!CanRequestSharedTask(task.id, request)) {
LogTasksDetail("[AttemptSharedTaskCreation] Shared task validation failed");
return;
}
auto request_members = GetRequestMembers(requested_character_id, request.characters);
if (!request_members.empty()) {
for (auto &m: request_members) {
LogTasksDetail(
"[AttemptSharedTaskCreation] Request Members ({})",
m.character_id
);
}
}
if (request_members.empty()) {
LogTasksDetail("[AttemptSharedTaskCreation] No additional request members found... Just leader");
}
for (auto& m: request.members) {
LogTasksDetail("[AttemptSharedTaskCreation] Request Members [{}]", m.character_name);
}
// new shared task instance
auto new_shared_task = SharedTask{};
@ -111,12 +78,12 @@ void SharedTaskManager::AttemptSharedTaskCreation(
// request timer lockouts
std::vector<CharacterTaskTimersRepository::CharacterTaskTimers> task_timers;
task_timers.reserve(request_members.size());
task_timers.reserve(request.members.size());
// persist members
std::vector<SharedTaskMembersRepository::SharedTaskMembers> shared_task_db_members = {};
shared_task_db_members.reserve(request_members.size());
for (auto &m: request_members) {
shared_task_db_members.reserve(request.members.size());
for (auto &m: request.members) {
auto e = SharedTaskMembersRepository::NewEntity();
e.character_id = m.character_id;
@ -183,13 +150,13 @@ void SharedTaskManager::AttemptSharedTaskCreation(
// set database data in memory to make it easier for any later referencing
new_shared_task.SetTaskData(task);
new_shared_task.SetTaskActivityData(activities);
new_shared_task.SetMembers(request_members);
new_shared_task.SetMembers(request.members);
// add to shared tasks list
auto& inserted = m_shared_tasks.emplace_back(new_shared_task);
// send accept to members
for (auto &m: request_members) {
for (auto &m: request.members) {
// only requester (leader) receives back the npc context to trigger task accept event
uint32_t npc_context_id = m.character_id == requested_character_id ? npc_type_id : 0;
SendAcceptNewSharedTaskPacket(
@ -208,50 +175,26 @@ void SharedTaskManager::AttemptSharedTaskCreation(
"[AttemptSharedTaskCreation] shared_task_id [{}] created successfully | task_id [{}] member_count [{}] activity_count [{}] current tasks in state [{}]",
new_shared_task.GetDbSharedTask().id,
task.id,
request_members.size(),
request.members.size(),
shared_task_activity_state.size(),
m_shared_tasks.size()
);
}
void SharedTaskManager::AttemptSharedTaskRemoval(
uint32 requested_task_id,
uint32 requested_character_id,
bool remove_from_db // inherited from zone logic - we're just passing through
)
void SharedTaskManager::RemoveMember(SharedTask* s, const SharedTaskMember& member, bool remove_from_db)
{
auto task = GetSharedTaskDataByTaskId(requested_task_id);
if (task.id != 0 && task.type == TASK_TYPE_SHARED) {
LogTasksDetail(
"[AttemptSharedTaskRemoval] Found Shared Task data ({}) [{}]",
requested_task_id,
task.title
);
}
LogTasksDetail("[RemoveMember] shared_task_id [{}] member [{}]", s->GetDbSharedTask().id, member.character_name);
auto t = FindSharedTaskByTaskIdAndCharacterId(requested_task_id, requested_character_id);
if (t) {
auto removed = t->FindMemberFromCharacterID(requested_character_id);
RemovePlayerFromSharedTask(s, member.character_id);
SendRemovePlayerFromSharedTaskPacket(member.character_id, s->GetDbSharedTask().task_id, remove_from_db);
// remove self
RemovePlayerFromSharedTask(t, requested_character_id);
SendRemovePlayerFromSharedTaskPacket(
requested_character_id,
requested_task_id,
remove_from_db
);
SendSharedTaskMemberRemovedToAllMembers(s, member.character_name);
// inform clients of removal of self
SendSharedTaskMemberRemovedToAllMembers(t, removed.character_name);
client_list.SendCharacterMessageID(member.character_id, Chat::Yellow,
TaskStr::PLAYER_REMOVED, {member.character_name, s->GetTaskData().title});
client_list.SendCharacterMessageID(
requested_character_id, Chat::Yellow,
SharedTaskMessage::PLAYER_HAS_BEEN_REMOVED, {removed.character_name, task.title}
);
if (removed.is_leader) {
ChooseNewLeader(t);
}
if (member.is_leader) {
ChooseNewLeader(s);
}
}
@ -270,18 +213,10 @@ void SharedTaskManager::RemoveEveryoneFromSharedTask(SharedTask *t, uint32 reque
SendRemovePlayerFromSharedTaskPacket(m.character_id, t->GetTaskData().id, true);
client_list.SendCharacterMessageID(
m.character_id, Chat::Yellow,
SharedTaskMessage::YOU_HAVE_BEEN_REMOVED, {t->GetTaskData().title}
);
client_list.SendCharacterMessageID(m.character_id, Chat::Yellow, TaskStr::YOU_REMOVED, {t->GetTaskData().title});
}
client_list.SendCharacterMessageID(
requested_character_id,
Chat::Red,
SharedTaskMessage::PLAYER_HAS_BEEN_REMOVED,
{"Everyone", t->GetTaskData().title}
);
client_list.SendCharacterMessageID(requested_character_id, Chat::Red, TaskStr::PLAYER_REMOVED, {"Everyone", t->GetTaskData().title});
RemoveAllMembersFromDynamicZones(t);
@ -721,14 +656,11 @@ void SharedTaskManager::SendRemovePlayerFromSharedTaskPacket(
)
{
// confirm shared task request: inform clients
auto p = std::make_unique<ServerPacket>(
ServerOP_SharedTaskAttemptRemove,
sizeof(ServerSharedTaskAttemptRemove_Struct)
);
auto p = std::make_unique<ServerPacket>(ServerOP_SharedTaskQuit, sizeof(ServerSharedTaskQuit_Struct));
auto d = reinterpret_cast<ServerSharedTaskAttemptRemove_Struct *>(p->pBuffer);
auto d = reinterpret_cast<ServerSharedTaskQuit_Struct *>(p->pBuffer);
d->requested_character_id = character_id;
d->requested_task_id = task_id;
d->task_id = task_id;
d->remove_from_db = remove_from_db;
// get requested character zone server
@ -870,48 +802,6 @@ void SharedTaskManager::PrintSharedTaskState()
}
}
void SharedTaskManager::RemovePlayerFromSharedTaskByPlayerName(SharedTask *s, const std::string &character_name)
{
auto member = s->FindMemberFromCharacterName(character_name);
if (member.character_id == 0) {
SendLeaderMessageID(s, Chat::Red, SharedTaskMessage::IS_NOT_MEMBER, {character_name});
return;
}
LogTasksDetail(
"[RemovePlayerFromSharedTaskByPlayerName] shared_task_id [{}] character_name [{}]",
s->GetDbSharedTask().id,
character_name
);
auto leader = s->GetLeader(); // get leader now for msg in case leader is one removed
RemovePlayerFromSharedTask(s, member.character_id);
SendRemovePlayerFromSharedTaskPacket(
member.character_id,
s->GetDbSharedTask().task_id,
true
);
SendSharedTaskMemberRemovedToAllMembers(s, member.character_name);
// leader and removed player get server messages (leader sees two messages)
// results in double messages if leader removed self (live behavior)
client_list.SendCharacterMessageID(
leader.character_id, Chat::Yellow,
SharedTaskMessage::PLAYER_HAS_BEEN_REMOVED, {member.character_name, s->GetTaskData().title}
);
client_list.SendCharacterMessageID(
member.character_id, Chat::Yellow,
SharedTaskMessage::PLAYER_HAS_BEEN_REMOVED, {member.character_name, s->GetTaskData().title}
);
if (member.is_leader) {
ChooseNewLeader(s);
}
}
void SharedTaskManager::SendSharedTaskMemberListToAllMembers(SharedTask *s)
{
// serialize once so we don't re-serialize it for every member
@ -944,7 +834,7 @@ void SharedTaskManager::MakeLeaderByPlayerName(SharedTask *s, const std::string
{
auto new_leader = s->FindMemberFromCharacterName(character_name);
if (new_leader.character_id == 0) {
SendLeaderMessageID(s, Chat::Red, SharedTaskMessage::IS_NOT_MEMBER, {character_name});
SendLeaderMessageID(s, Chat::Red, TaskStr::IS_NOT_MEMBER, {character_name});
return;
}
@ -977,10 +867,7 @@ void SharedTaskManager::MakeLeaderByPlayerName(SharedTask *s, const std::string
s->SetMembers(members);
SaveMembers(s, members);
SendSharedTaskMemberListToAllMembers(s);
SendMembersMessageID(
s, Chat::Yellow, SharedTaskMessage::PLAYER_NOW_LEADER,
{new_leader.character_name, s->GetTaskData().title}
);
SendMembersMessageID(s, Chat::Yellow, TaskStr::PLAYER_NOW_LEADER, {new_leader.character_name, s->GetTaskData().title});
for (const auto &dz_id : s->dynamic_zone_ids) {
auto dz = DynamicZone::FindDynamicZoneByID(dz_id);
@ -1051,7 +938,7 @@ void SharedTaskManager::SendSharedTaskInvitePacket(SharedTask *s, int64 invited_
// get requested character zone server
ClientListEntry *cle = client_list.FindCLEByCharacterID(invited_character_id);
if (cle && cle->Server()) {
SendLeaderMessageID(s, Chat::Yellow, SharedTaskMessage::SEND_INVITE_TO, {cle->name()});
SendLeaderMessageID(s, Chat::Yellow, TaskStr::SEND_INVITE_TO, {cle->name()});
cle->Server()->SendPacket(p.get());
}
}
@ -1325,11 +1212,7 @@ std::vector<CharacterTaskTimersRepository::CharacterTaskTimers> SharedTaskManage
return task_timers;
}
bool SharedTaskManager::CanRequestSharedTask(
uint32_t task_id,
uint32_t character_id,
const SharedTaskRequestCharacters &request
)
bool SharedTaskManager::CanRequestSharedTask(uint32_t task_id, const SharedTaskRequest& request)
{
auto task = GetSharedTaskDataByTaskId(task_id);
if (task.id == 0) {
@ -1342,38 +1225,15 @@ bool SharedTaskManager::CanRequestSharedTask(
auto shared_task_members = FindCharactersInSharedTasks(request.character_ids);
if (!shared_task_members.empty()) {
// messages for every character already in a shared task
for (const auto &member : shared_task_members) {
auto it = std::find_if(
request.characters.begin(), request.characters.end(),
[&](const CharacterDataRepository::CharacterData &char_data) {
return char_data.id == member;
}
);
if (it != request.characters.end()) {
if (it->id == character_id) {
client_list.SendCharacterMessageID(
character_id,
Chat::Red,
SharedTaskMessage::NO_REQUEST_BECAUSE_HAVE_ONE
);
}
else if (request.group_type == SharedTaskRequestGroupType::Group) {
client_list.SendCharacterMessageID(
character_id,
Chat::Red,
SharedTaskMessage::NO_REQUEST_BECAUSE_GROUP_HAS_ONE,
{it->name}
);
}
else {
client_list.SendCharacterMessageID(
character_id,
Chat::Red,
SharedTaskMessage::NO_REQUEST_BECAUSE_RAID_HAS_ONE,
{it->name}
);
}
for (const auto& it : shared_task_members) {
if (it.character_id == request.leader_id) {
client_list.SendCharacterMessageID(it.character_id, Chat::Red, TaskStr::REQUEST_HAVE);
}
else if (request.group_type == SharedTaskRequestGroupType::Group) {
client_list.SendCharacterMessageID(it.character_id, Chat::Red, TaskStr::REQUEST_GROUP_HAS, {it.character_name});
}
else {
client_list.SendCharacterMessageID(it.character_id, Chat::Red, TaskStr::REQUEST_RAID_HAS, {it.character_name});
}
}
@ -1382,40 +1242,36 @@ bool SharedTaskManager::CanRequestSharedTask(
// check if any party member's minimum level is too low (pre-2014 this was average level)
if (task.minlevel > 0 && request.lowest_level < task.minlevel) {
client_list.SendCharacterMessageID(character_id, Chat::Red, SharedTaskMessage::AVG_LVL_LOW);
client_list.SendCharacterMessage(request.leader_id, Chat::Red, TaskStr::Get(TaskStr::LVL_TOO_LOW));
return false;
}
// check if any party member's maximum level is too high (pre-2014 this was average level)
if (task.maxlevel > 0 && request.highest_level > task.maxlevel) {
client_list.SendCharacterMessageID(character_id, Chat::Red, SharedTaskMessage::AVG_LVL_HIGH);
client_list.SendCharacterMessage(request.leader_id, Chat::Red, TaskStr::Get(TaskStr::LVL_TOO_HIGH));
return false;
}
// allow gm/dev bypass for minimum player count requirements
auto requester = client_list.FindCLEByCharacterID(character_id);
auto requester = client_list.FindCLEByCharacterID(request.leader_id);
bool is_gm = (requester && requester->GetGM());
// check if party member count is below the minimum
if (!is_gm && task.min_players > 0 && request.characters.size() < task.min_players) {
client_list.SendCharacterMessageID(
character_id,
Chat::Red,
SharedTaskMessage::SHARED_TASK_NOT_MEET_MIN_NUM_PLAYER
);
if (!is_gm && task.min_players > 0 && request.members.size() < task.min_players) {
client_list.SendCharacterMessageID(request.leader_id, Chat::Red, TaskStr::MIN_PLAYERS);
return false;
}
// check if party member count is above the maximum
// todo: live creates the shared task but truncates members if it exceeds max (sorted by leader and raid group numbers)
if (task.max_players > 0 && request.characters.size() > task.max_players) {
client_list.SendCharacterMessageID(character_id, Chat::Red, SharedTaskMessage::PARTY_EXCEED_MAX_PLAYER);
if (task.max_players > 0 && request.members.size() > task.max_players) {
client_list.SendCharacterMessageID(request.leader_id, Chat::Red, TaskStr::MAX_PLAYERS);
return false;
}
// check if party level spread exceeds task's maximum
if (task.level_spread > 0 && (request.highest_level - request.lowest_level) > task.level_spread) {
client_list.SendCharacterMessageID(character_id, Chat::Red, SharedTaskMessage::LVL_SPREAD_HIGH);
client_list.SendCharacterMessageID(request.leader_id, Chat::Red, TaskStr::LVL_SPREAD_HIGH);
return false;
}
@ -1429,51 +1285,28 @@ bool SharedTaskManager::CanRequestSharedTask(
auto hours = fmt::format_int((seconds / 3600) % 24).str();
auto mins = fmt::format_int((seconds / 60) % 60).str();
if (character_task_timers.front().character_id == character_id) {
if (character_task_timers.front().character_id == request.leader_id) {
if (timer_type == TaskTimerType::Replay) {
client_list.SendCharacterMessageID(
character_id,
Chat::Red,
SharedTaskMessage::YOU_MUST_WAIT_REPLAY_TIMER, {days, hours, mins}
);
client_list.SendCharacterMessageID(request.leader_id, Chat::Red, TaskStr::YOU_REPLAY_TIMER, {days, hours, mins});
}
else if (timer_type == TaskTimerType::Request) {
client_list.SendCharacterMessage(
character_id,
Chat::Red, fmt::format(
SharedTaskMessage::GetEQStr(SharedTaskMessage::YOU_MUST_WAIT_REQUEST_TIMER), days, hours, mins
)
);
client_list.SendCharacterMessage(request.leader_id, Chat::Red, fmt::format(
TaskStr::Get(TaskStr::YOU_REQUEST_TIMER), days, hours, mins));
}
}
else {
auto it = std::find_if(
request.characters.begin(), request.characters.end(),
[&](const CharacterDataRepository::CharacterData &char_data) {
return char_data.id == character_task_timers.front().character_id;
}
);
auto it = std::find_if(request.members.begin(), request.members.end(),
[&](const SharedTaskMember& member) {
return member.character_id == character_task_timers.front().character_id;
});
if (it != request.characters.end() && timer_type == TaskTimerType::Replay) {
client_list.SendCharacterMessageID(
character_id,
Chat::Red,
SharedTaskMessage::PLAYER_MUST_WAIT_REPLAY_TIMER,
{it->name, days, hours, mins}
);
if (it != request.members.end() && timer_type == TaskTimerType::Replay) {
client_list.SendCharacterMessageID(request.leader_id, Chat::Red,
TaskStr::PLAYER_REPLAY_TIMER, {it->character_name, days, hours, mins});
}
else if (it != request.characters.end() && timer_type == TaskTimerType::Request) {
client_list.SendCharacterMessage(
character_id,
Chat::Red,
fmt::format(
SharedTaskMessage::GetEQStr(SharedTaskMessage::PLAYER_MUST_WAIT_REQUEST_TIMER),
it->name,
days,
hours,
mins
)
);
else if (it != request.members.end() && timer_type == TaskTimerType::Request) {
client_list.SendCharacterMessage(request.leader_id, Chat::Red, fmt::format(
TaskStr::Get(TaskStr::PLAYER_REQUEST_TIMER), it->character_name, days, hours, mins));
}
}
@ -1491,15 +1324,15 @@ bool SharedTaskManager::CanAddPlayer(SharedTask *s, uint32_t character_id, std::
// check if task is locked
if (s->GetDbSharedTask().is_locked) {
SendLeaderMessageID(s, Chat::Red, SharedTaskMessage::TASK_NOT_ALLOWING_PLAYERS_AT_TIME);
SendLeaderMessageID(s, Chat::Red, TaskStr::NOT_ALLOWING_PLAYERS);
allow_invite = false;
}
// check if player is online and in cle (other checks require online)
auto cle = client_list.FindCLEByCharacterID(character_id);
if (!cle || !cle->Server()) {
SendLeaderMessageID(s, Chat::Red, SharedTaskMessage::PLAYER_NOT_ONLINE_TO_ADD, {player_name});
SendLeaderMessageID(s, Chat::Red, SharedTaskMessage::COULD_NOT_BE_INVITED, {player_name});
SendLeaderMessageID(s, Chat::Red, TaskStr::PLAYER_NOT_ONLINE, {player_name});
SendLeaderMessageID(s, Chat::Red, TaskStr::COULD_NOT_BE_INVITED, {player_name});
return false;
}
@ -1514,10 +1347,10 @@ bool SharedTaskManager::CanAddPlayer(SharedTask *s, uint32_t character_id, std::
if (!shared_task_members.empty()) {
auto shared_task_id = shared_task_members.front().shared_task_id;
if (shared_task_id == s->GetDbSharedTask().id) {
SendLeaderMessageID(s, Chat::Red, SharedTaskMessage::CANT_ADD_PLAYER_ALREADY_MEMBER, {player_name});
SendLeaderMessageID(s, Chat::Red, TaskStr::PLAYER_ALREADY_MEMBER, {player_name});
}
else {
SendLeaderMessageID(s, Chat::Red, SharedTaskMessage::CANT_ADD_PLAYER_ALREADY_ASSIGNED, {player_name});
SendLeaderMessageID(s, Chat::Red, TaskStr::PLAYER_ALREADY_ASSIGNED, {player_name});
}
allow_invite = false;
}
@ -1526,15 +1359,10 @@ bool SharedTaskManager::CanAddPlayer(SharedTask *s, uint32_t character_id, std::
for (const auto &invite : m_active_invitations) {
if (invite.character_id == character_id) {
if (invite.shared_task_id == s->GetDbSharedTask().id) {
SendLeaderMessageID(
s,
Chat::Red,
SharedTaskMessage::PLAYER_ALREADY_OUTSTANDING_INVITATION_THIS,
{player_name}
);
SendLeaderMessageID(s, Chat::Red, TaskStr::PLAYER_INVITED, {player_name});
}
else {
SendLeaderMessageID(s, Chat::Red, SharedTaskMessage::PLAYER_ALREADY_OUTSTANDING_ANOTHER, {player_name});
SendLeaderMessageID(s, Chat::Red, TaskStr::PLAYER_INVITED_OTHER, {player_name});
}
allow_invite = false;
break;
@ -1553,24 +1381,11 @@ bool SharedTaskManager::CanAddPlayer(SharedTask *s, uint32_t character_id, std::
auto mins = fmt::format_int((seconds / 60) % 60).str();
if (timer_type == TaskTimerType::Replay) {
SendLeaderMessageID(
s,
Chat::Red,
SharedTaskMessage::CANT_ADD_PLAYER_REPLAY_TIMER, {player_name, days, hours, mins}
);
SendLeaderMessageID(s, Chat::Red, TaskStr::CANT_ADD_PLAYER_REPLAY_TIMER, {player_name, days, hours, mins});
}
else {
SendLeaderMessage(
s,
Chat::Red,
fmt::format(
SharedTaskMessage::GetEQStr(SharedTaskMessage::CANT_ADD_PLAYER_REQUEST_TIMER),
player_name,
days,
hours,
mins
)
);
SendLeaderMessage(s, Chat::Red, fmt::format(
TaskStr::Get(TaskStr::CANT_ADD_PLAYER_REQUEST_TIMER), player_name, days, hours, mins));
}
allow_invite = false;
@ -1579,7 +1394,7 @@ bool SharedTaskManager::CanAddPlayer(SharedTask *s, uint32_t character_id, std::
// check if task has maximum players
if (s->GetTaskData().max_players > 0 && s->GetMembers().size() >= s->GetTaskData().max_players) {
auto max = fmt::format_int(s->GetTaskData().max_players).str();
SendLeaderMessageID(s, Chat::Red, SharedTaskMessage::CANT_ADD_PLAYER_MAX_PLAYERS, {max});
SendLeaderMessageID(s, Chat::Red, TaskStr::CANT_ADD_MAX_PLAYERS, {max});
allow_invite = false;
}
@ -1603,29 +1418,29 @@ bool SharedTaskManager::CanAddPlayer(SharedTask *s, uint32_t character_id, std::
if ((highest_level - lowest_level) > s->GetTaskData().level_spread) {
auto max_spread = fmt::format_int(s->GetTaskData().level_spread).str();
SendLeaderMessageID(s, Chat::Red, SharedTaskMessage::CANT_ADD_PLAYER_MAX_LEVEL_SPREAD, {max_spread});
SendLeaderMessageID(s, Chat::Red, TaskStr::CANT_ADD_LVL_SPREAD, {max_spread});
allow_invite = false;
}
}
// check if player is below minimum level of task (pre-2014 this was average level)
if (s->GetTaskData().minlevel > 0 && cle->level() < s->GetTaskData().minlevel) {
SendLeaderMessageID(s, Chat::Red, SharedTaskMessage::CANT_ADD_PLAYER_FALL_MIN_AVG_LEVEL);
SendLeaderMessage(s, Chat::Red, TaskStr::Get(TaskStr::CANT_ADD_MIN_LEVEL));
allow_invite = false;
}
// check if player is above maximum level of task (pre-2014 this was average level)
if (s->GetTaskData().maxlevel > 0 && cle->level() > s->GetTaskData().maxlevel) {
SendLeaderMessageID(s, Chat::Red, SharedTaskMessage::CANT_ADD_PLAYER_MAX_AVERAGE_LEVEL);
SendLeaderMessage(s, Chat::Red, TaskStr::Get(TaskStr::CANT_ADD_MAX_LEVEL));
allow_invite = false;
}
if (!allow_invite) {
if (!accepted) {
SendLeaderMessageID(s, Chat::Red, SharedTaskMessage::COULD_NOT_BE_INVITED, {player_name});
SendLeaderMessageID(s, Chat::Red, TaskStr::COULD_NOT_BE_INVITED, {player_name});
}
else {
SendLeaderMessageID(s, Chat::Red, SharedTaskMessage::ACCEPTED_OFFER_TO_JOIN_BUT_COULD_NOT, {player_name});
SendLeaderMessageID(s, Chat::Red, TaskStr::COULD_NOT_JOIN, {player_name});
}
}
@ -1704,7 +1519,7 @@ void SharedTaskManager::AddReplayTimers(SharedTask *s)
member_id,
Chat::Yellow,
fmt::format(
SharedTaskMessage::GetEQStr(SharedTaskMessage::RECEIVED_REPLAY_TIMER),
TaskStr::Get(TaskStr::RECEIVED_REPLAY_TIMER),
s->GetTaskData().title,
fmt::format_int(seconds / 86400).c_str(), // days
fmt::format_int((seconds / 3600) % 24).c_str(), // hours
@ -1731,9 +1546,9 @@ void SharedTaskManager::AddReplayTimers(SharedTask *s)
}
// memory search
std::vector<uint32_t> SharedTaskManager::FindCharactersInSharedTasks(const std::vector<uint32_t> &find_characters)
std::vector<SharedTaskMember> SharedTaskManager::FindCharactersInSharedTasks(const std::vector<uint32_t> &find_characters)
{
std::vector<uint32_t> characters = {};
std::vector<SharedTaskMember> characters = {};
for (auto &s: m_shared_tasks) {
// loop through members
@ -1742,7 +1557,7 @@ std::vector<uint32_t> SharedTaskManager::FindCharactersInSharedTasks(const std::
for (auto &find_character_id: find_characters) {
// found character, add to list
if (find_character_id == m.character_id) {
characters.emplace_back(m.character_id);
characters.emplace_back(m);
}
}
}
@ -1829,7 +1644,7 @@ void SharedTaskManager::LockTask(SharedTask* s, bool lock)
if (lock)
{
SendLeaderMessageID(s, Chat::Yellow, SharedTaskMessage::YOUR_TASK_NOW_LOCKED);
SendLeaderMessageID(s, Chat::Yellow, TaskStr::TASK_LOCKED);
}
}
}

View File

@ -33,15 +33,8 @@ public:
TasksRepository::Tasks GetSharedTaskDataByTaskId(uint32 task_id);
std::vector<TaskActivitiesRepository::TaskActivities> GetSharedTaskActivityDataByTaskId(uint32 task_id);
// gets group / raid members belonging to requested character
std::vector<SharedTaskMember> GetRequestMembers(
uint32 requestor_character_id,
const std::vector<CharacterDataRepository::CharacterData> &characters
);
// client attempting to create a shared task
void AttemptSharedTaskCreation(uint32 requested_task_id, uint32 requested_character_id, uint32 npc_type_id);
void AttemptSharedTaskRemoval(uint32 requested_task_id, uint32 requested_character_id, bool remove_from_db);
// shared task activity update middleware
void SharedTaskActivityUpdate(
@ -72,7 +65,7 @@ public:
);
void RemovePlayerFromSharedTask(SharedTask *s, uint32 character_id);
void PrintSharedTaskState();
void RemovePlayerFromSharedTaskByPlayerName(SharedTask *s, const std::string &character_name);
void RemoveMember(SharedTask* s, const SharedTaskMember& member, bool remove_from_db);
void RemoveEveryoneFromSharedTask(SharedTask *s, uint32 requested_character_id);
void MakeLeaderByPlayerName(SharedTask *s, const std::string &character_name);
@ -120,7 +113,7 @@ protected:
void AddReplayTimers(SharedTask *s);
bool CanAddPlayer(SharedTask *s, uint32_t character_id, std::string player_name, bool accepted);
bool CanRequestSharedTask(uint32_t task_id, uint32_t character_id, const SharedTaskRequestCharacters &request);
bool CanRequestSharedTask(uint32_t task_id, const SharedTaskRequest& request);
void ChooseNewLeader(SharedTask *s);
bool HandleCompletedActivities(SharedTask* s);
void HandleCompletedTask(SharedTask* s);
@ -133,7 +126,7 @@ protected:
void RemoveAllMembersFromDynamicZones(SharedTask *s);
// memory search
std::vector<uint32_t> FindCharactersInSharedTasks(const std::vector<uint32_t> &find_characters);
std::vector<SharedTaskMember> FindCharactersInSharedTasks(const std::vector<uint32_t> &find_characters);
};
#endif //EQEMU_SHARED_TASK_MANAGER_H

View File

@ -38,21 +38,22 @@ void SharedTaskWorldMessaging::HandleZoneMessage(ServerPacket *pack)
break;
}
case ServerOP_SharedTaskAttemptRemove: {
auto *r = (ServerSharedTaskAttemptRemove_Struct *) pack->pBuffer;
case ServerOP_SharedTaskQuit: {
auto *r = (ServerSharedTaskQuit_Struct *) pack->pBuffer;
LogTasksDetail(
"[ServerOP_SharedTaskAttemptRemove] Received request from character [{}] task_id [{}] remove_from_db [{}]",
r->requested_character_id,
r->requested_task_id,
r->remove_from_db
);
shared_task_manager.AttemptSharedTaskRemoval(
r->requested_task_id,
"[ServerOP_SharedTaskQuit] Received request from character [{}] task_id [{}] remove_from_db [{}]",
r->requested_character_id,
r->task_id,
r->remove_from_db
);
auto s = shared_task_manager.FindSharedTaskByTaskIdAndCharacterId(r->task_id, r->requested_character_id);
if (s) {
auto member = s->FindMemberFromCharacterID(r->requested_character_id);
if (member.character_id != 0) {
shared_task_manager.RemoveMember(s, member, r->remove_from_db);
}
}
break;
}
case ServerOP_SharedTaskKickPlayers: {
@ -67,10 +68,7 @@ void SharedTaskWorldMessaging::HandleZoneMessage(ServerPacket *pack)
if (t) {
auto leader = t->GetLeader();
if (leader.character_id != r->source_character_id) {
client_list.SendCharacterMessageID(
r->source_character_id, Chat::Red,
SharedTaskMessage::YOU_ARE_NOT_LEADER_COMMAND_ISSUE, {leader.character_name}
);
client_list.SendCharacterMessageID(r->source_character_id, Chat::Red, TaskStr::NOT_LEADER, {leader.character_name});
}
else {
shared_task_manager.RemoveEveryoneFromSharedTask(t, r->source_character_id);
@ -146,10 +144,7 @@ void SharedTaskWorldMessaging::HandleZoneMessage(ServerPacket *pack)
auto leader = t->GetLeader();
if (leader.character_id != r->source_character_id) {
client_list.SendCharacterMessageID(
r->source_character_id, Chat::Red,
SharedTaskMessage::YOU_ARE_NOT_LEADER_COMMAND_ISSUE, {leader.character_name}
);
client_list.SendCharacterMessageID(r->source_character_id, Chat::Red, TaskStr::NOT_LEADER, {leader.character_name});
}
else {
LogTasksDetail(
@ -158,8 +153,14 @@ void SharedTaskWorldMessaging::HandleZoneMessage(ServerPacket *pack)
t->GetDbSharedTask().id
);
std::string character_name = r->player_name;
shared_task_manager.RemovePlayerFromSharedTaskByPlayerName(t, character_name);
auto member = t->FindMemberFromCharacterName(r->player_name);
if (member.character_id == 0) {
shared_task_manager.SendLeaderMessageID(t, Chat::Red, TaskStr::IS_NOT_MEMBER, {r->player_name});
}
else {
shared_task_manager.RemoveMember(t, member, true);
shared_task_manager.SendLeaderMessageID(t, Chat::Yellow, TaskStr::PLAYER_REMOVED, {member.character_name, t->GetTaskData().title});
}
}
}
@ -185,17 +186,10 @@ void SharedTaskWorldMessaging::HandleZoneMessage(ServerPacket *pack)
auto leader = t->GetLeader();
if (leader.character_id != r->source_character_id) {
client_list.SendCharacterMessageID(
r->source_character_id, Chat::Red,
SharedTaskMessage::YOU_ARE_NOT_LEADER_COMMAND_ISSUE, {leader.character_name}
);
client_list.SendCharacterMessageID(r->source_character_id, Chat::Red, TaskStr::NOT_LEADER, {leader.character_name});
}
else if (strcasecmp(leader.character_name.c_str(), r->player_name) == 0) {
client_list.SendCharacterMessageID(
r->source_character_id,
Chat::Red,
SharedTaskMessage::YOU_ALREADY_LEADER
);
client_list.SendCharacterMessageID(r->source_character_id, Chat::Red, TaskStr::YOU_ALREADY_LEADER);
}
else {
LogTasksDetail(
@ -232,10 +226,7 @@ void SharedTaskWorldMessaging::HandleZoneMessage(ServerPacket *pack)
auto leader = t->GetLeader();
if (leader.character_id != r->source_character_id) {
// taskadd is client sided with System color in newer clients, server side might still be red
client_list.SendCharacterMessageID(
r->source_character_id, Chat::Red,
SharedTaskMessage::YOU_ARE_NOT_LEADER_COMMAND_ISSUE, {leader.character_name}
);
client_list.SendCharacterMessageID(r->source_character_id, Chat::Red, TaskStr::NOT_LEADER, {leader.character_name});
}
else {
LogTasksDetail(
@ -275,12 +266,7 @@ void SharedTaskWorldMessaging::HandleZoneMessage(ServerPacket *pack)
shared_task_manager.AddPlayerByCharacterIdAndName(t, r->source_character_id, r->player_name);
}
else {
shared_task_manager.SendLeaderMessageID(
t,
Chat::Red,
SharedTaskMessage::PLAYER_DECLINED_OFFER,
{r->player_name}
);
shared_task_manager.SendLeaderMessageID(t, Chat::Red, TaskStr::PLAYER_DECLINED_OFFER, {r->player_name});
}
}
break;
@ -333,18 +319,12 @@ void SharedTaskWorldMessaging::HandleZoneMessage(ServerPacket *pack)
player_names.emplace_back(member.character_name);
if (member.is_leader) {
client_list.SendCharacterMessageID(
buf->source_character_id, Chat::Yellow,
SharedTaskMessage::LEADER_PRINT, {member.character_name}
);
client_list.SendCharacterMessageID(buf->source_character_id, Chat::Yellow, TaskStr::LEADER_PRINT, {member.character_name});
}
}
std::string player_list = fmt::format("{}", fmt::join(player_names, ", "));
client_list.SendCharacterMessageID(
buf->source_character_id, Chat::Yellow,
SharedTaskMessage::MEMBERS_PRINT, {player_list}
);
client_list.SendCharacterMessageID(buf->source_character_id, Chat::Yellow, TaskStr::MEMBERS_PRINT, {player_list});
}
break;

View File

@ -1385,7 +1385,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
}
case ServerOP_SharedTaskRequest:
case ServerOP_SharedTaskAddPlayer:
case ServerOP_SharedTaskAttemptRemove:
case ServerOP_SharedTaskQuit:
case ServerOP_SharedTaskUpdate:
case ServerOP_SharedTaskRequestMemberlist:
case ServerOP_SharedTaskRemovePlayer:

View File

@ -15420,7 +15420,7 @@ void Client::Handle_OP_SharedTaskAddPlayer(const EQApplicationPacket *app)
if (!GetTaskState()->HasActiveSharedTask()) {
// this message is generated client-side in newer clients
Message(Chat::System, SharedTaskMessage::GetEQStr(SharedTaskMessage::COULD_NOT_USE_COMMAND));
Message(Chat::System, TaskStr::Get(TaskStr::COULD_NOT_USE_COMMAND));
}
else {
// struct

View File

@ -53,11 +53,11 @@ void SharedTaskZoneMessaging::HandleWorldMessage(ServerPacket *pack)
break;
}
case ServerOP_SharedTaskAttemptRemove: {
auto p = reinterpret_cast<ServerSharedTaskAttemptRemove_Struct *>(pack->pBuffer);
case ServerOP_SharedTaskQuit: {
auto p = reinterpret_cast<ServerSharedTaskQuit_Struct *>(pack->pBuffer);
auto c = entity_list.GetClientByCharID(p->requested_character_id);
if (c) {
LogTasks("[ServerOP_SharedTaskAttemptRemove] We're back in zone and I found [{}]", c->GetCleanName());
LogTasks("[ServerOP_SharedTaskQuit] We're back in zone and I found [{}]", c->GetCleanName());
c->m_requested_shared_task_removal = true;
c->GetTaskState()->CancelTask(

View File

@ -2103,12 +2103,12 @@ void ClientTaskState::CancelTask(Client *c, int sequence_number, TaskType task_t
if (!c->m_requested_shared_task_removal && task_type == TaskType::Shared && m_active_shared_task.task_id != 0) {
// struct
auto pack = new ServerPacket(ServerOP_SharedTaskAttemptRemove, sizeof(ServerSharedTaskAttemptRemove_Struct));
auto *r = (ServerSharedTaskAttemptRemove_Struct *) pack->pBuffer;
auto pack = new ServerPacket(ServerOP_SharedTaskQuit, sizeof(ServerSharedTaskQuit_Struct));
auto *r = (ServerSharedTaskQuit_Struct *) pack->pBuffer;
// fill
r->requested_character_id = c->CharacterID();
r->requested_task_id = m_active_shared_task.task_id;
r->task_id = m_active_shared_task.task_id;
r->remove_from_db = remove_from_db;
// send
@ -2351,16 +2351,14 @@ void ClientTaskState::AcceptNewTask(
auto mins = fmt::format_int((seconds / 60) % 60).str();
// these solo task messages are in SharedTaskMessage for convenience
namespace EQStr = SharedTaskMessage;
if (timer_type == TaskTimerType::Replay)
{
int eqstr_id = EQStr::TASK_ASSIGN_WAIT_REPLAY_TIMER;
client->MessageString(Chat::Red, eqstr_id, days.c_str(), hours.c_str(), mins.c_str());
client->MessageString(Chat::Red, TaskStr::ASSIGN_REPLAY_TIMER, days.c_str(), hours.c_str(), mins.c_str());
}
else if (timer_type == TaskTimerType::Request)
{
int eqstr_id = EQStr::TASK_ASSIGN_WAIT_REQUEST_TIMER;
client->Message(Chat::Red, fmt::format(EQStr::GetEQStr(eqstr_id), days, hours, mins).c_str());
auto eqstr = TaskStr::Get(TaskStr::ASSIGN_REQUEST_TIMER);
client->Message(Chat::Red, fmt::format(eqstr, days, hours, mins).c_str());
}
return;
@ -2444,7 +2442,7 @@ void ClientTaskState::AcceptNewTask(
}
client->Message(Chat::Yellow, fmt::format(
SharedTaskMessage::GetEQStr(SharedTaskMessage::RECEIVED_REQUEST_TIMER),
TaskStr::Get(TaskStr::RECEIVED_REQUEST_TIMER),
task->title,
fmt::format_int(seconds / 86400).c_str(), // days
fmt::format_int((seconds / 3600) % 24).c_str(), // hours
@ -2625,19 +2623,19 @@ void ClientTaskState::ListTaskTimers(Client* client)
if (timer_type == TaskTimerType::Replay)
{
client->MessageString(Chat::Yellow, SharedTaskMessage::REPLAY_TIMER_REMAINING,
client->MessageString(Chat::Yellow, TaskStr::REPLAY_TIMER_REMAINING,
task->title.c_str(), days.c_str(), hours.c_str(), mins.c_str());
}
else
{
auto eqstr = SharedTaskMessage::GetEQStr(SharedTaskMessage::REQUEST_TIMER_REMAINING);
auto eqstr = TaskStr::Get(TaskStr::REQUEST_TIMER_REMAINING);
client->Message(Chat::Yellow, fmt::format(eqstr, task->title, days, hours, mins).c_str());
}
}
}
if (character_task_timers.empty()) {
client->MessageString(Chat::Yellow, SharedTaskMessage::YOU_NO_CURRENT_REPLAY_TIMERS);
client->MessageString(Chat::Yellow, TaskStr::NO_REPLAY_TIMERS);
}
}
@ -2666,7 +2664,7 @@ void ClientTaskState::AddReplayTimer(Client* client, ClientTaskInformation& clie
CharacterTaskTimersRepository::InsertOne(database, timer);
client->Message(Chat::Yellow, fmt::format(
SharedTaskMessage::GetEQStr(SharedTaskMessage::RECEIVED_REPLAY_TIMER),
TaskStr::Get(TaskStr::RECEIVED_REPLAY_TIMER),
task.title,
fmt::format_int(task.replay_timer_seconds / 86400).c_str(), // days
fmt::format_int((task.replay_timer_seconds / 3600) % 24).c_str(), // hours

View File

@ -696,11 +696,12 @@ void TaskManager::SharedTaskSelector(Client *client, Mob *mob, int count, const
// check if requester already has a shared task (no need to query group/raid members if so)
if (client->GetTaskState()->HasActiveSharedTask()) {
client->MessageString(Chat::Red, SharedTaskMessage::NO_REQUEST_BECAUSE_HAVE_ONE);
client->MessageString(Chat::Red, TaskStr::REQUEST_HAVE);
return;
}
// get group/raid member character data from db (need to query for character ids)
// todo: group/raids need refactored to avoid queries and ignore offline members (through world)
auto request = SharedTask::GetRequestCharacters(database, client->CharacterID());
// check if any group/raid member already has a shared task (already checked solo character)
@ -713,25 +714,17 @@ void TaskManager::SharedTaskSelector(Client *client, Mob *mob, int count, const
if (!shared_task_members.empty()) {
validation_failed = true;
auto it = std::find_if(
request.characters.begin(), request.characters.end(),
[&](const CharacterDataRepository::CharacterData &char_data) {
return char_data.id == shared_task_members.front().character_id;
}
);
auto it = std::find_if(request.members.begin(), request.members.end(),
[&](const SharedTaskMember& member) {
return member.character_id == shared_task_members.front().character_id;
});
if (it != request.characters.end()) {
if (it != request.members.end()) {
if (request.group_type == SharedTaskRequestGroupType::Group) {
client->MessageString(
Chat::Red,
SharedTaskMessage::NO_REQUEST_BECAUSE_GROUP_HAS_ONE,
it->name.c_str());
client->MessageString(Chat::Red, TaskStr::REQUEST_GROUP_HAS, it->character_name.c_str());
}
else {
client->MessageString(
Chat::Red,
SharedTaskMessage::NO_REQUEST_BECAUSE_RAID_HAS_ONE,
it->name.c_str());
client->MessageString(Chat::Red, TaskStr::REQUEST_RAID_HAS, it->character_name.c_str());
}
}
}
@ -758,7 +751,7 @@ void TaskManager::SharedTaskSelector(Client *client, Mob *mob, int count, const
SendSharedTaskSelector(client, mob, task_list_index, task_list);
}
else {
client->MessageString(Chat::Red, SharedTaskMessage::YOU_DO_NOT_MEET_REQ_AVAILABLE);
client->MessageString(Chat::Red, TaskStr::NOT_MEET_REQ);
}
}
}
@ -1748,7 +1741,7 @@ void TaskManager::SyncClientSharedTaskRemoveLocalIfNotExists(Client *c, ClientTa
CharacterTasksRepository::DeleteWhere(database, delete_where);
CharacterActivitiesRepository::DeleteWhere(database, delete_where);
c->MessageString(Chat::Yellow, SharedTaskMessage::YOU_ARE_NO_LONGER_A_MEMBER,
c->MessageString(Chat::Yellow, TaskStr::NO_LONGER_MEMBER_TITLE,
m_task_data[cts->m_active_shared_task.task_id]->title.c_str());
// remove as active task if doesn't exist

View File

@ -3236,7 +3236,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
}
case ServerOP_SharedTaskAcceptNewTask:
case ServerOP_SharedTaskUpdate:
case ServerOP_SharedTaskAttemptRemove:
case ServerOP_SharedTaskQuit:
case ServerOP_SharedTaskMemberlist:
case ServerOP_SharedTaskMemberChange:
case ServerOP_SharedTaskInvitePlayer: