Battleground Queue fixes (#4648)

* Fixes #4644.
* Initialize all battleground queues at startup to reduce overhead of creation/deletion during live server.
* Removes lots of duplicate code between team checks.
* Adds missing checks for script commands bg_leave and bg_desert to only warp players out using the Battleground Queue System.
* Adds documentation for script commands bg_leave and bg_desert to state players will be warped out after when using the Battleground Queue System.
* Optimizes join logic to add new players to the end of the queue rather than the front.
* Cleans up the client messages so certain responses are cleared when they need to be.
Thanks to @Balferian and @Lemongrass3110!
This commit is contained in:
Aleos 2020-02-20 22:25:14 -05:00 committed by GitHub
parent 55645b8d3d
commit 1fc4b8de20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 187 additions and 386 deletions

View File

@ -9390,6 +9390,9 @@ Note: 'bg_reserve' and 'bg_unbook' prevent the Battlegrounds queue from joining
Same as 'bg_leave' but slaps the player with a deserter status so they can't enter another queue for the time
defined in battleground_db (10 minutes by default).
With the Battleground Queue System, it will also warp the player to their previous position when they joined or
to their save point if the map had MF_NOSAVE.
---------------------------------------
*bg_warp <Battle Group>,"<map name>",<x>,<y>;
@ -9451,6 +9454,9 @@ OnTimer1000:
Removes attached player from their Battle Group.
With the Battleground Queue System, it will also warp the player to their previous position when they joined or
to their save point if the map had MF_NOSAVE.
---------------------------------------
*bg_destroy <Batte Group>;

View File

@ -538,7 +538,8 @@ bat_b01,10,294,3 script Vintenar#bat_b01_aover 419,{
close;
}
bg_leave;
warp "bat_room",154,150;
if (!getbattleflag("feature.bgqueue"))
warp "bat_room",154,150;
end;
OnInit:
@ -562,7 +563,8 @@ bat_b01,389,14,3 script Vintenar#bat_b01_bover 415,{
close;
}
bg_leave;
warp "bat_room",154,150;
if (!getbattleflag("feature.bgqueue"))
warp "bat_room",154,150;
end;
OnInit:

View File

@ -539,7 +539,8 @@ bat_b02,10,294,3 script Vintenar#bat_b02_aover 419,{
close;
}
bg_leave;
warp "bat_room",154,150;
if (!getbattleflag("feature.bgqueue"))
warp "bat_room",154,150;
end;
OnInit:
@ -563,7 +564,8 @@ bat_b02,389,14,3 script Vintenar#bat_b02_bover 415,{
close;
}
bg_leave;
warp "bat_room",154,150;
if (!getbattleflag("feature.bgqueue"))
warp "bat_room",154,150;
end;
OnInit:

View File

@ -375,8 +375,8 @@ bat_c02,51,130,5 script KVM Officer#KVM02A 419,{
set Bat_Team,0;
if (!getbattleflag("feature.bgqueue"))
warp "bat_room",154,150;
end;
}
end;
}
bat_c02,148,53,1 duplicate(KVM Officer#KVM02A) KVM Officer#KVM02B 415

View File

@ -374,8 +374,8 @@ bat_c03,51,130,5 script KVM Officer#KVM03A 419,{
}
bg_leave;
set Bat_Team,0;
if (!getbattleflag("feature.bgqueue"))
warp "bat_room",154,150;
if (!getbattleflag("feature.bgqueue"))
warp "bat_room",154,150;
}
end;
}

View File

@ -723,7 +723,7 @@ bat_a02,45,19,3 script Croix Vintenar#a02_b 415,{
callfunc "F_BG_Badge",1,"Croix","Tierra";
}
bg_leave;
if (getbattleflag("feature.bgqueue"))
if (!getbattleflag("feature.bgqueue"))
warp "bat_room",154,150;
end;

View File

@ -420,22 +420,26 @@ int bg_team_leave(struct map_session_data *sd, bool quit, bool deserter)
sd->bg_id = 0;
if (bgteam) {
char output[CHAT_SIZE_MAX];
int i;
// Warping members out only applies to the Battleground Queue System
if (battle_config.feature_bgqueue) {
auto member = bgteam->members.begin();
ARR_FIND(0, bgteam->members.size(), i, bgteam->members[i].sd == sd);
if (i < bgteam->members.size()) { // Removes member from BG
if (bgteam->members[i].entry_point.map != 0) {
int16 map_id = map_mapindex2mapid(bgteam->members[i].entry_point.map);
while (member != bgteam->members.end()) {
if (member->sd == sd && member->entry_point.map != 0) {
if (!map_getmapflag(map_mapindex2mapid(member->entry_point.map), MF_NOSAVE))
pc_setpos(sd, member->entry_point.map, member->entry_point.x, member->entry_point.y, CLR_TELEPORT);
else
pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); // Warp to save point if the entry map has no save flag.
if (!map_getmapflag(map_id, MF_NOSAVE))
pc_setpos(sd, bgteam->members[i].entry_point.map, bgteam->members[i].entry_point.x, bgteam->members[i].entry_point.y, CLR_TELEPORT);
else
pc_setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); // Warp to save point if the entry map has no save flag.
bgteam->members.erase(member);
break;
} else
member++;
}
util::erase_at(bgteam->members, i);
}
char output[CHAT_SIZE_MAX];
if (quit)
sprintf(output, "Server: %s has quit the game...", sd->status.name);
else
@ -681,7 +685,9 @@ static TIMER_FUNC(bg_on_ready_start)
nullpo_retr(1, queue);
bg_queue_start_battleground(std::shared_ptr<s_battleground_queue>(queue));
queue->tid_start = INVALID_TIMER;
bg_queue_start_battleground(queue);
return 0;
}
@ -794,154 +800,25 @@ bool bg_queue_reservation(const char *name, bool state)
return false;
}
/**
* Initialize a Battleground queue
* @param bg_id: Battleground ID
* @param req_players: Required amount of players
* @return s_battleground_queue*
*/
std::shared_ptr<s_battleground_queue> bg_queue_create(int bg_id, int req_players)
{
auto queue = std::make_shared<s_battleground_queue>();
queue->id = bg_id;
queue->required_players = req_players;
queue->accepted_players = 0;
queue->tid_expire = INVALID_TIMER;
queue->tid_start = INVALID_TIMER;
queue->tid_requeue = INVALID_TIMER;
queue->in_ready_state = false;
return queue;
}
/**
* Allow a player to join a Battleground queue
* @param name: Battleground name
* @param sd: Player data
* @return @see e_bg_queue_apply_ack
*/
e_bg_queue_apply_ack bg_queue_join(const char *name, struct map_session_data *sd)
{
if (!sd) {
ShowError("bg_queue_join: Tried to join non-existent player.\n.");
return BG_APPLY_NONE;
}
if (!bg_queue_check_status(sd, name))
return BG_APPLY_NONE;
if (bg_player_is_in_bg_map(sd)) {
clif_messagecolor(&sd->bl, color_table[COLOR_LIGHT_GREEN], msg_txt(sd, 337), false, SELF); // You may not join a battleground queue when you're in a battleground map.
return BG_APPLY_NONE;
}
std::shared_ptr<s_battleground_type> bg = bg_search_name(name);
if (!bg) {
ShowWarning("bq_queue_join: Could not find battleground \"%s\" requested by %s (AID: %d / CID: %d)\n", name, sd->status.name, sd->status.account_id, sd->status.char_id);
return BG_APPLY_INVALID_NAME;
}
if (bg->min_lvl && sd->status.base_level < bg->min_lvl)
return BG_APPLY_PLAYER_LEVEL; // Level too low
if (bg->max_lvl && sd->status.base_level > bg->max_lvl)
return BG_APPLY_PLAYER_LEVEL; // Level too high
std::shared_ptr<s_battleground_queue> queue;
bool r;
if (bg_queues.empty()) {
r = rnd() % 2 != 0;
queue = bg_queue_create(bg->id, bg->required_players);
if (!r)
queue->teama_members.push_back(sd);
else
queue->teamb_members.push_back(sd);
sd->bg_queue = queue;
bg_queues.insert(bg_queues.begin(), queue);
return BG_APPLY_ACCEPT;
} else {
r = rnd() % 2 != 0;
for (const auto &it : bg_queues) {
try {
queue = it;
} catch (std::out_of_range &) {
continue;
}
if (queue->in_ready_state)
continue;
if (!r) {
if (queue->teama_members.size() != queue->required_players) {
sd->bg_queue = queue;
queue->teama_members.push_back(sd);
if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined
bg_queue_on_ready(name, queue);
return BG_APPLY_ACCEPT;
} else if (queue->teamb_members.size() != queue->required_players) {
sd->bg_queue = queue;
queue->teamb_members.push_back(sd);
if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined
bg_queue_on_ready(name, queue);
return BG_APPLY_ACCEPT;
}
} else {
if (queue->teamb_members.size() != queue->required_players) {
sd->bg_queue = queue;
queue->teamb_members.push_back(sd);
if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined
bg_queue_on_ready(name, queue);
return BG_APPLY_ACCEPT;
} else if (queue->teama_members.size() != queue->required_players) {
sd->bg_queue = queue;
queue->teama_members.push_back(sd);
if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined
bg_queue_on_ready(name, queue);
return BG_APPLY_ACCEPT;
}
}
}
}
queue = bg_queue_create(bg->id, bg->required_players);
r = rnd() % 2 != 0;
if (!r)
queue->teama_members.push_back(sd);
else
queue->teamb_members.push_back(sd);
sd->bg_queue = queue;
bg_queues.insert(bg_queues.begin(), queue);
return BG_APPLY_ACCEPT;
}
/**
* Join a party onto the same side of a Battleground
* @param name: Battleground name
* @param sd: Player who requested to join the battlegrounds
* @return @see e_bg_queue_apply_ack
*/
e_bg_queue_apply_ack bg_queue_join_party(const char *name, struct map_session_data *sd)
void bg_queue_join_party(const char *name, struct map_session_data *sd)
{
struct party_data *p = party_search(sd->status.party_id);
if (!p)
return BG_APPLY_INVALID_APP; // Someone has bypassed the client check for being in a party
if (!p) {
clif_bg_queue_apply_result(BG_APPLY_INVALID_APP, name, sd);
return; // Someone has bypassed the client check for being in a party
}
for (const auto &it : p->party.member) {
if (it.leader && sd->status.char_id != it.char_id)
return BG_APPLY_PARTYGUILD_LEADER; // Not the party leader
if (it.leader && sd->status.char_id != it.char_id) {
clif_bg_queue_apply_result(BG_APPLY_PARTYGUILD_LEADER, name, sd);
return; // Not the party leader
}
}
std::shared_ptr<s_battleground_type> bg = bg_search_name(name);
@ -954,8 +831,10 @@ e_bg_queue_apply_ack bg_queue_join_party(const char *name, struct map_session_da
p_online++;
}
if (p_online > bg->max_players)
return BG_APPLY_PLAYER_COUNT; // Too many party members online
if (p_online > bg->max_players) {
clif_bg_queue_apply_result(BG_APPLY_PLAYER_COUNT, name, sd);
return; // Too many party members online
}
std::vector<struct map_session_data *> list;
@ -971,10 +850,11 @@ e_bg_queue_apply_ack bg_queue_join_party(const char *name, struct map_session_da
}
}
return bg_queue_join_multi(name, sd, list); // Join as party, all on the same side of the BG
bg_queue_join_multi(name, sd, list); // Join as party, all on the same side of the BG
} else {
ShowWarning("clif_parse_bg_queue_apply_request: Could not find Battleground: \"%s\" requested by player: %s (AID:%d CID:%d)\n", name, sd->status.name, sd->status.account_id, sd->status.char_id);
return BG_APPLY_INVALID_NAME; // Invalid BG name
clif_bg_queue_apply_result(BG_APPLY_INVALID_NAME, name, sd);
return; // Invalid BG name
}
}
@ -982,30 +862,29 @@ e_bg_queue_apply_ack bg_queue_join_party(const char *name, struct map_session_da
* Join a guild onto the same side of a Battleground
* @param name: Battleground name
* @param sd: Player who requested to join the battlegrounds
* @return @see e_bg_queue_apply_ack
*/
e_bg_queue_apply_ack bg_queue_join_guild(const char *name, struct map_session_data *sd)
void bg_queue_join_guild(const char *name, struct map_session_data *sd)
{
if (!sd->guild)
return BG_APPLY_INVALID_APP; // Someone has bypassed the client check for being in a guild
if (!sd->guild) {
clif_bg_queue_apply_result(BG_APPLY_INVALID_APP, name, sd);
return; // Someone has bypassed the client check for being in a guild
}
if (strcmp(sd->status.name, sd->guild->master) != 0)
return BG_APPLY_PARTYGUILD_LEADER; // Not the guild leader
if (strcmp(sd->status.name, sd->guild->master) != 0) {
clif_bg_queue_apply_result(BG_APPLY_PARTYGUILD_LEADER, name, sd);
return; // Not the guild leader
}
std::shared_ptr<s_battleground_type> bg = bg_search_name(name);
if (bg) {
struct guild *g = guild_search(sd->status.guild_id);
int g_online = 0;
struct guild* g = sd->guild;
for (const auto &it : g->member) {
if (it.online)
g_online++;
if (g->connect_member > bg->max_players) {
clif_bg_queue_apply_result(BG_APPLY_PLAYER_COUNT, name, sd);
return; // Too many guild members online
}
if (g_online > bg->max_players)
return BG_APPLY_PLAYER_COUNT; // Too many guild members online
std::vector<struct map_session_data *> list;
for (const auto &it : g->member) {
@ -1020,10 +899,11 @@ e_bg_queue_apply_ack bg_queue_join_guild(const char *name, struct map_session_da
}
}
return bg_queue_join_multi(name, sd, list); // Join as guild, all on the same side of the BG
bg_queue_join_multi(name, sd, list); // Join as guild, all on the same side of the BG
} else {
ShowWarning("clif_parse_bg_queue_apply_request: Could not find Battleground: \"%s\" requested by player: %s (AID:%d CID:%d)\n", name, sd->status.name, sd->status.account_id, sd->status.char_id);
return BG_APPLY_INVALID_NAME; // Invalid BG name
clif_bg_queue_apply_result(BG_APPLY_INVALID_NAME, name, sd);
return; // Invalid BG name
}
}
@ -1032,186 +912,102 @@ e_bg_queue_apply_ack bg_queue_join_guild(const char *name, struct map_session_da
* @param name: Battleground name
* @param sd: Player who requested to join the battlegrounds
* @param list: Contains all players including the player who requested to join
* @return @see e_bg_queue_apply_ack
*/
e_bg_queue_apply_ack bg_queue_join_multi(const char *name, struct map_session_data *sd, std::vector <map_session_data *> list)
void bg_queue_join_multi(const char *name, struct map_session_data *sd, std::vector <map_session_data *> list)
{
if (!sd) {
ShowError("bg_queue_join_multi: Tried to join non-existent player\n.");
return BG_APPLY_NONE;
}
if (!bg_queue_check_status(sd, name))
return BG_APPLY_NONE;
if (bg_player_is_in_bg_map(sd)) {
clif_messagecolor(&sd->bl, color_table[COLOR_LIGHT_GREEN], msg_txt(sd, 337), false, SELF); // You may not join a battleground queue when you're in a battleground map.
return BG_APPLY_NONE;
return;
}
std::shared_ptr<s_battleground_type> bg = bg_search_name(name);
if (!bg) {
ShowWarning("bq_queue_join_multi: Could not find battleground \"%s\" requested by %s (AID: %d / CID: %d)\n", name, sd->status.name, sd->status.account_id, sd->status.char_id);
return BG_APPLY_INVALID_NAME;
return;
}
if (bg->min_lvl && sd->status.base_level < bg->min_lvl)
return BG_APPLY_PLAYER_LEVEL; // Level too low
if (bg->max_lvl && sd->status.base_level > bg->max_lvl)
return BG_APPLY_PLAYER_LEVEL; // Level too high
if (bg_queues.empty()) {
std::shared_ptr<s_battleground_queue> queue = bg_queue_create(bg->id, bg->required_players);
bool r = rnd() % 2 != 0;
if (!r) {
while (!list.empty() && queue->teama_members.size() < bg->required_players) {
struct map_session_data *sd2 = list.back();
list.pop_back();
if (!sd2 || sd2->bg_queue)
continue;
if (!bg_queue_check_joinable(bg, sd2, name))
continue;
sd2->bg_queue = queue;
clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2);
clif_bg_queue_apply_notify(name, sd2);
queue->teama_members.insert(queue->teama_members.begin(), sd2);
}
} else {
while (!list.empty() && queue->teamb_members.size() < bg->required_players) {
struct map_session_data *sd2 = list.back();
list.pop_back();
if (!sd2 || sd2->bg_queue)
continue;
if (!bg_queue_check_joinable(bg, sd2, name))
continue;
sd2->bg_queue = queue;
clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2);
clif_bg_queue_apply_notify(name, sd2);
queue->teamb_members.insert(queue->teamb_members.begin(), sd2);
}
}
bg_queues.insert(bg_queues.begin(), queue);
return BG_APPLY_ACCEPT;
} else {
std::shared_ptr<s_battleground_queue> queue;
bool r = rnd() % 2 != 0;
for (const auto &it : bg_queues) {
try {
queue = it;
} catch (std::out_of_range &) {
continue;
}
if (queue->in_ready_state)
continue;
if (queue->teama_members.size() + list.size() <= bg->required_players || queue->teamb_members.size() + list.size() <= bg->required_players) { // Make sure there's enough space on one side to join as a party/guild in this queue
if (!r && queue->teama_members.size() + list.size() <= bg->required_players) {
while (!list.empty() && queue->teama_members.size() < bg->required_players) {
struct map_session_data *sd2 = list.back();
list.pop_back();
if (!sd2 || sd2->bg_queue)
continue;
if (!bg_queue_check_joinable(bg, sd2, name))
continue;
sd2->bg_queue = queue;
clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2);
clif_bg_queue_apply_notify(name, sd2);
queue->teama_members.insert(queue->teama_members.begin(), sd2);
}
if (queue->teama_members.size() == bg->required_players && queue->teamb_members.size() == bg->required_players) // Enough players have joined
bg_queue_on_ready(name, queue);
return BG_APPLY_ACCEPT;
} else {
while (!list.empty() && queue->teamb_members.size() < bg->required_players) {
struct map_session_data *sd2 = list.back();
list.pop_back();
if (!sd2)
continue;
if (!bg_queue_check_joinable(bg, sd2, name))
continue;
sd2->bg_queue = queue;
clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2);
clif_bg_queue_apply_notify(name, sd2);
queue->teamb_members.insert(queue->teamb_members.begin(), sd2);
}
}
return BG_APPLY_ACCEPT;
}
}
// Create a new queue if none of the existing ones are joinable for this party/guild
queue = nullptr;
queue = bg_queue_create(bg->id, bg->required_players);
r = rnd() % 2 != 0;
if (!r) {
while (!list.empty() && queue->teama_members.size() < bg->required_players) {
struct map_session_data *sd2 = list.back();
list.pop_back();
if (!sd2 || sd2->bg_queue)
continue;
if (!bg_queue_check_joinable(bg, sd2, name))
continue;
sd2->bg_queue = queue;
clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2);
clif_bg_queue_apply_notify(name, sd2);
queue->teama_members.insert(queue->teama_members.begin(), sd2);
}
} else {
while (!list.empty() && queue->teamb_members.size() < bg->required_players) {
struct map_session_data *sd2 = list.back();
list.pop_back();
if (!sd2 || sd2->bg_queue)
continue;
if (!bg_queue_check_joinable(bg, sd2, name))
continue;
sd2->bg_queue = queue;
clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2);
clif_bg_queue_apply_notify(name, sd2);
queue->teamb_members.insert(queue->teamb_members.begin(), sd2);
}
}
bg_queues.insert(bg_queues.begin(), queue);
return BG_APPLY_ACCEPT;
if (!bg_queue_check_joinable(bg, sd, name)){
return;
}
return BG_APPLY_RECONNECT; // Something went wrong, sends reconnect and then reapply message to client.
for (const auto &queue : bg_queues) {
if (queue->id != bg->id)
continue;
if (queue->in_ready_state)
continue;
// Make sure there's enough space on one side to join as a party/guild in this queue
if (queue->teama_members.size() + list.size() > bg->required_players && queue->teamb_members.size() + list.size() > bg->required_players) {
break;
}
bool r = rnd() % 2 != 0;
std::vector<map_session_data *>* team = r ? &queue->teamb_members : &queue->teama_members;
// If the designated team is full, put the player into the other team
if (team->size() + list.size() > bg->required_players) {
team = r ? &queue->teama_members : &queue->teamb_members;
}
while (!list.empty() && team->size() < bg->required_players) {
struct map_session_data *sd2 = list.back();
list.pop_back();
if (!sd2 || sd2->bg_queue)
continue;
if (!bg_queue_check_joinable(bg, sd2, name))
continue;
sd2->bg_queue = queue;
team->push_back(sd2);
clif_bg_queue_apply_result(BG_APPLY_ACCEPT, name, sd2);
clif_bg_queue_apply_notify(name, sd2);
}
// Enough players have joined
if (queue->teamb_members.size() == bg->required_players && queue->teama_members.size() == bg->required_players)
bg_queue_on_ready(name, queue);
return;
}
// Something went wrong, sends reconnect and then reapply message to client.
clif_bg_queue_apply_result(BG_APPLY_RECONNECT, name, sd);
}
/**
* Clear Battleground queue for next one
* @param queue: Queue to clean up
*/
static void bg_queue_clear(s_battleground_queue *queue)
{
if (!queue)
return;
if (queue->tid_requeue != INVALID_TIMER) {
delete_timer(queue->tid_requeue, bg_on_ready_loopback);
queue->tid_requeue = INVALID_TIMER;
}
if (queue->tid_expire != INVALID_TIMER) {
delete_timer(queue->tid_expire, bg_on_ready_expire);
queue->tid_expire = INVALID_TIMER;
}
if (queue->tid_start != INVALID_TIMER) {
delete_timer(queue->tid_start, bg_on_ready_start);
queue->tid_start = INVALID_TIMER;
}
if (queue->map != nullptr) {
queue->map->isReserved = false; // Remove reservation to free up for future queue
queue->map = nullptr;
}
queue->in_ready_state = false;
queue->accepted_players = 0; // Reset the queue count
}
/**
@ -1238,22 +1034,12 @@ static bool bg_queue_leave_sub(struct map_session_data *sd, std::vector<map_sess
sd->bg_queue_accept_state = false;
}
list_it = lista.erase(list_it);
lista.erase(list_it);
if (lista.empty() && listb.empty()) { // If there are no players left in the queue, discard it
auto queue_it = bg_queues.begin();
while (queue_it != bg_queues.end()) {
std::shared_ptr<s_battleground_queue> q = *queue_it;
if (sd->bg_queue == q) {
if (q->tid_requeue != INVALID_TIMER && get_timer(q->tid_requeue)) {
delete_timer(q->tid_requeue, bg_on_ready_loopback);
q->tid_requeue = INVALID_TIMER;
}
queue_it = bg_queues.erase(queue_it);
}
for (auto &queue : bg_queues) {
if (sd->bg_queue == queue)
bg_queue_clear(queue.get());
}
}
@ -1349,7 +1135,7 @@ void bg_queue_on_accept_invite(std::shared_ptr<s_battleground_queue> queue, stru
if (queue->accepted_players == queue->required_players * 2) {
queue->tid_start = add_timer(gettick() + battleground_db.find(queue->id)->start_delay * 1000, bg_on_ready_start, 0, (intptr_t)queue.get());
if (queue->tid_expire != INVALID_TIMER && get_timer(queue->tid_expire)) {
if (queue->tid_expire != INVALID_TIMER) {
delete_timer(queue->tid_expire, bg_on_ready_expire);
queue->tid_expire = INVALID_TIMER;
}
@ -1360,13 +1146,8 @@ void bg_queue_on_accept_invite(std::shared_ptr<s_battleground_queue> queue, stru
* Begin the Battleground from the given queue
* @param queue: Battleground queue
*/
void bg_queue_start_battleground(std::shared_ptr<s_battleground_queue> queue)
void bg_queue_start_battleground(s_battleground_queue *queue)
{
if (queue->tid_start != INVALID_TIMER && get_timer(queue->tid_start)) {
delete_timer(queue->tid_start, bg_on_ready_start);
queue->tid_start = INVALID_TIMER;
}
std::shared_ptr<s_battleground_type> bg = battleground_db.find(queue->id);
if (!bg) {
@ -1401,15 +1182,28 @@ void bg_queue_start_battleground(std::shared_ptr<s_battleground_queue> queue)
queue->teamb_members.clear();
queue->teama_members.shrink_to_fit();
queue->teamb_members.shrink_to_fit();
bg_queue_clear(queue);
}
auto queue_it = bg_queues.begin();
/**
* Initialize a Battleground queue
* @param bg_id: Battleground ID
* @param req_players: Required amount of players
* @return s_battleground_queue*
*/
static void bg_queue_create(int bg_id, int req_players)
{
auto queue = std::make_shared<s_battleground_queue>();
while (queue_it != bg_queues.end()) {
if (*queue_it == queue)
queue_it = bg_queues.erase(queue_it);
}
queue->id = bg_id;
queue->required_players = req_players;
queue->accepted_players = 0;
queue->tid_expire = INVALID_TIMER;
queue->tid_start = INVALID_TIMER;
queue->tid_requeue = INVALID_TIMER;
queue->in_ready_state = false;
return;
bg_queues.push_back(queue);
}
/**
@ -1417,9 +1211,13 @@ void bg_queue_start_battleground(std::shared_ptr<s_battleground_queue> queue)
*/
void do_init_battleground(void)
{
if (battle_config.feature_bgqueue)
if (battle_config.feature_bgqueue) {
battleground_db.load();
for (const auto &bg : battleground_db)
bg_queue_create(bg.first, bg.second->required_players);
}
add_timer_func_list(bg_send_xy_timer, "bg_send_xy_timer");
add_timer_func_list(bg_on_ready_loopback, "bg_on_ready_loopback");
add_timer_func_list(bg_on_ready_expire, "bg_on_ready_expire");

View File

@ -126,15 +126,13 @@ int bg_team_leave(struct map_session_data *sd, bool quit, bool deserter);
bool bg_team_warp(int bg_id, unsigned short mapindex, short x, short y);
bool bg_player_is_in_bg_map(struct map_session_data *sd);
bool bg_queue_check_joinable(std::shared_ptr<s_battleground_type> bg, struct map_session_data *sd, const char *name);
std::shared_ptr<s_battleground_queue> bg_queue_create(int bg_id, int req_players);
e_bg_queue_apply_ack bg_queue_join(const char *name, struct map_session_data *sd);
e_bg_queue_apply_ack bg_queue_join_party(const char *name, struct map_session_data *sd);
e_bg_queue_apply_ack bg_queue_join_guild(const char *name, struct map_session_data *sd);
e_bg_queue_apply_ack bg_queue_join_multi(const char *name, struct map_session_data *sd, std::vector<map_session_data *> list);
void bg_queue_join_party(const char *name, struct map_session_data *sd);
void bg_queue_join_guild(const char *name, struct map_session_data *sd);
void bg_queue_join_multi(const char *name, struct map_session_data *sd, std::vector<map_session_data *> list);
bool bg_queue_leave(struct map_session_data *sd);
bool bg_queue_on_ready(const char *name, std::shared_ptr<s_battleground_queue> queue);
void bg_queue_on_accept_invite(std::shared_ptr<s_battleground_queue> queue, struct map_session_data *sd);
void bg_queue_start_battleground(std::shared_ptr<s_battleground_queue> queue);
void bg_queue_start_battleground(s_battleground_queue *queue);
bool bg_member_respawn(struct map_session_data *sd);
void bg_send_message(struct map_session_data *sd, const char *mes, int len);

View File

@ -17482,7 +17482,6 @@ void clif_parse_bg_queue_apply_request(int fd, struct map_session_data *sd)
short type = RFIFOW(fd,2);
char name[NAME_LENGTH];
e_bg_queue_apply_ack result;
safestrncpy(name, RFIFOCP(fd, 4), NAME_LENGTH);
@ -17491,20 +17490,16 @@ void clif_parse_bg_queue_apply_request(int fd, struct map_session_data *sd)
clif_bg_queue_apply_result(BG_APPLY_DUPLICATE, name, sd); // Duplicate application warning
return;
} else if (type == 1) // Solo
result = bg_queue_join(name, sd);
bg_queue_join_multi(name, sd, { sd });
else if (type == 2) // Party
result = bg_queue_join_party(name, sd);
bg_queue_join_party(name, sd);
else if (type == 4) // Guild
result = bg_queue_join_guild(name, sd);
bg_queue_join_guild(name, sd);
else {
ShowWarning("clif_parse_bg_queue_apply_request: Received invalid queue type: %d from player %s (AID:%d CID:%d).\n", type, sd->status.name, sd->status.account_id, sd->status.char_id);
clif_bg_queue_apply_result(BG_APPLY_INVALID_APP, name, sd); // Someone sent an invalid queue type packet
return;
}
clif_bg_queue_apply_result(result, name, sd);
if (result == BG_APPLY_ACCEPT)
clif_bg_queue_apply_notify(name, sd);
}
/// Outgoing battlegrounds queue apply result.