fix team member count updates
This commit is contained in:
+7
-15
@@ -3488,32 +3488,24 @@ struct C_ChangeTeamMemberPrivilegeLevel_BB_11EA {
|
|||||||
le_uint32_t guild_card_number = 0;
|
le_uint32_t guild_card_number = 0;
|
||||||
} __packed_ws__(C_ChangeTeamMemberPrivilegeLevel_BB_11EA, 4);
|
} __packed_ws__(C_ChangeTeamMemberPrivilegeLevel_BB_11EA, 4);
|
||||||
|
|
||||||
// 12EA (S->C): Team membership information
|
// 12EA (S->C): Update team membership
|
||||||
// This updates the client's view of its system file.
|
// This updates the client's view of its system file.
|
||||||
|
|
||||||
struct S_TeamMembershipInformation_BB_12EA {
|
struct S_UpdateTeamMembership_BB_12EA {
|
||||||
// If skip_update_system_file is not zero, the client ignores the command.
|
// If skip_update_system_file is not zero, the client ignores the command.
|
||||||
// It's not clear why this field exists.
|
// It's not clear why this field exists.
|
||||||
le_uint32_t skip_update_system_file = 0;
|
le_uint32_t skip_update_system_file = 0;
|
||||||
PSOBBBaseTeamMembership membership;
|
PSOBBBaseTeamMembership membership;
|
||||||
} __packed_ws__(S_TeamMembershipInformation_BB_12EA, 0x38);
|
} __packed_ws__(S_UpdateTeamMembership_BB_12EA, 0x38);
|
||||||
|
|
||||||
// 13EA: Team info for lobby players
|
// 13EA: Team info for lobby players
|
||||||
// header.flag specifies the number of entries.
|
// header.flag specifies the number of entries.
|
||||||
|
|
||||||
struct S_TeamInfoForPlayer_BB_13EA_15EA_Entry {
|
struct S_TeamInfoForPlayer_BB_13EA_15EA_Entry {
|
||||||
// The client uses the first four of these to determine if the player is in a
|
// The client uses the first four fields of the membership to determine if
|
||||||
// team or not - if they are all zero, the player is not in a team.
|
// the player is in a team: if any are nonzero, the player is in a team.
|
||||||
/* 0000 */ le_uint32_t guild_card_number = 0;
|
/* 0000 */ PSOBBBaseTeamMembership membership;
|
||||||
/* 0004 */ le_uint32_t team_id = 0;
|
/* 0034 */ le_uint32_t guild_card_number = 0;
|
||||||
/* 0008 */ le_uint32_t reward_flags = 0;
|
|
||||||
/* 000C */ le_uint32_t unknown_a6 = 0;
|
|
||||||
/* 0010 */ uint8_t privilege_level = 0;
|
|
||||||
/* 0011 */ uint8_t team_member_count = 0;
|
|
||||||
/* 0012 */ uint8_t unknown_a8 = 0;
|
|
||||||
/* 0013 */ uint8_t unknown_a9 = 0;
|
|
||||||
/* 0014 */ pstring<TextEncoding::UTF16_ALWAYS_MARKED, 0x10> team_name;
|
|
||||||
/* 0034 */ le_uint32_t guild_card_number2 = 0;
|
|
||||||
/* 0038 */ le_uint32_t lobby_client_id = 0;
|
/* 0038 */ le_uint32_t lobby_client_id = 0;
|
||||||
/* 003C */ pstring<TextEncoding::UTF16_ALWAYS_MARKED, 0x10> player_name;
|
/* 003C */ pstring<TextEncoding::UTF16_ALWAYS_MARKED, 0x10> player_name;
|
||||||
/* 005C */ parray<le_uint16_t, 0x20 * 0x20> flag_data;
|
/* 005C */ parray<le_uint16_t, 0x20 * 0x20> flag_data;
|
||||||
|
|||||||
+12
-38
@@ -5237,7 +5237,7 @@ static void on_EA_BB(shared_ptr<Client> c, uint16_t command, uint32_t flag, stri
|
|||||||
c->login->account->save();
|
c->login->account->save();
|
||||||
|
|
||||||
send_command(c, 0x02EA, 0x00000000);
|
send_command(c, 0x02EA, 0x00000000);
|
||||||
send_team_membership_change_notifications(c);
|
send_team_metadata_change_notifications(s, team, c->login->account->account_id, TeamMetadataChange::TEAM_CREATED);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5271,10 +5271,10 @@ static void on_EA_BB(shared_ptr<Client> c, uint16_t command, uint32_t flag, stri
|
|||||||
team->team_id,
|
team->team_id,
|
||||||
added_c->login->account->account_id,
|
added_c->login->account->account_id,
|
||||||
added_c->character()->disp.name.decode(added_c->language()));
|
added_c->character()->disp.name.decode(added_c->language()));
|
||||||
|
|
||||||
send_team_membership_change_notifications(added_c);
|
|
||||||
send_command(c, 0x04EA, 0x00000000);
|
send_command(c, 0x04EA, 0x00000000);
|
||||||
send_command(added_c, 0x04EA, 0x00000000);
|
send_command(added_c, 0x04EA, 0x00000000);
|
||||||
|
send_team_metadata_change_notifications(
|
||||||
|
s, team, added_c->login->account->account_id, TeamMetadataChange::TEAM_MEMBER_COUNT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5302,9 +5302,8 @@ static void on_EA_BB(shared_ptr<Client> c, uint16_t command, uint32_t flag, stri
|
|||||||
} catch (const out_of_range&) {
|
} catch (const out_of_range&) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (removed_c) {
|
send_team_metadata_change_notifications(
|
||||||
send_team_membership_change_notifications(removed_c);
|
s, team, removed_c->login->account->account_id, TeamMetadataChange::TEAM_MEMBER_COUNT);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// TODO: Figure out the right error code to use here.
|
// TODO: Figure out the right error code to use here.
|
||||||
send_command(c, 0x06EA, 0x00000001);
|
send_command(c, 0x06EA, 0x00000001);
|
||||||
@@ -5348,7 +5347,7 @@ static void on_EA_BB(shared_ptr<Client> c, uint16_t command, uint32_t flag, stri
|
|||||||
if (team && team->members.at(c->login->account->account_id).check_flag(TeamIndex::Team::Member::Flag::IS_MASTER)) {
|
if (team && team->members.at(c->login->account->account_id).check_flag(TeamIndex::Team::Member::Flag::IS_MASTER)) {
|
||||||
const auto& cmd = check_size_t<C_SetTeamFlag_BB_0FEA>(data);
|
const auto& cmd = check_size_t<C_SetTeamFlag_BB_0FEA>(data);
|
||||||
s->team_index->set_flag_data(team->team_id, cmd.flag_data);
|
s->team_index->set_flag_data(team->team_id, cmd.flag_data);
|
||||||
send_team_metadata_change_notifications(s, team, TeamMetadataChange::FLAG_DATA);
|
send_team_metadata_change_notifications(s, team, 0, TeamMetadataChange::FLAG_DATA);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5357,7 +5356,7 @@ static void on_EA_BB(shared_ptr<Client> c, uint16_t command, uint32_t flag, stri
|
|||||||
if (team && team->members.at(c->login->account->account_id).check_flag(TeamIndex::Team::Member::Flag::IS_MASTER)) {
|
if (team && team->members.at(c->login->account->account_id).check_flag(TeamIndex::Team::Member::Flag::IS_MASTER)) {
|
||||||
s->team_index->disband(team->team_id);
|
s->team_index->disband(team->team_id);
|
||||||
send_command(c, 0x10EA, 0x00000000);
|
send_command(c, 0x10EA, 0x00000000);
|
||||||
send_team_metadata_change_notifications(s, team, TeamMetadataChange::TEAM_DISBANDED);
|
send_team_metadata_change_notifications(s, team, 0, TeamMetadataChange::TEAM_DISBANDED);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5370,14 +5369,11 @@ static void on_EA_BB(shared_ptr<Client> c, uint16_t command, uint32_t flag, stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The client only sends this command with flag = 0x00, 0x30, or 0x40
|
// The client only sends this command with flag = 0x00, 0x30, or 0x40
|
||||||
bool send_updates_for_this_m = false;
|
|
||||||
bool send_updates_for_other_m = false;
|
|
||||||
bool send_master_transfer_updates = false;
|
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
case 0x00: // Demote member
|
case 0x00: // Demote member
|
||||||
if (s->team_index->demote_leader(c->login->account->account_id, cmd.guild_card_number)) {
|
if (s->team_index->demote_leader(c->login->account->account_id, cmd.guild_card_number)) {
|
||||||
send_command(c, 0x11EA, 0x00000000);
|
send_command(c, 0x11EA, 0x00000000);
|
||||||
send_updates_for_other_m = true;
|
send_team_metadata_change_notifications(s, team, cmd.guild_card_number, 0);
|
||||||
} else {
|
} else {
|
||||||
send_command(c, 0x11EA, 0x00000005);
|
send_command(c, 0x11EA, 0x00000005);
|
||||||
}
|
}
|
||||||
@@ -5385,7 +5381,7 @@ static void on_EA_BB(shared_ptr<Client> c, uint16_t command, uint32_t flag, stri
|
|||||||
case 0x30: // Promote member
|
case 0x30: // Promote member
|
||||||
if (s->team_index->promote_leader(c->login->account->account_id, cmd.guild_card_number)) {
|
if (s->team_index->promote_leader(c->login->account->account_id, cmd.guild_card_number)) {
|
||||||
send_command(c, 0x11EA, 0x00000000);
|
send_command(c, 0x11EA, 0x00000000);
|
||||||
send_updates_for_other_m = true;
|
send_team_metadata_change_notifications(s, team, cmd.guild_card_number, 0);
|
||||||
} else {
|
} else {
|
||||||
send_command(c, 0x11EA, 0x00000005);
|
send_command(c, 0x11EA, 0x00000005);
|
||||||
}
|
}
|
||||||
@@ -5393,33 +5389,11 @@ static void on_EA_BB(shared_ptr<Client> c, uint16_t command, uint32_t flag, stri
|
|||||||
case 0x40: // Transfer master
|
case 0x40: // Transfer master
|
||||||
s->team_index->change_master(c->login->account->account_id, cmd.guild_card_number);
|
s->team_index->change_master(c->login->account->account_id, cmd.guild_card_number);
|
||||||
send_command(c, 0x11EA, 0x00000000);
|
send_command(c, 0x11EA, 0x00000000);
|
||||||
send_updates_for_this_m = true;
|
send_team_metadata_change_notifications(s, team, cmd.guild_card_number, TeamMetadataChange::TEAM_MASTER);
|
||||||
send_updates_for_other_m = true;
|
|
||||||
send_master_transfer_updates = true;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw runtime_error("invalid privilege level");
|
throw runtime_error("invalid privilege level");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (send_master_transfer_updates) {
|
|
||||||
for (const auto& it : team->members) {
|
|
||||||
try {
|
|
||||||
auto other_c = s->find_client(nullptr, it.second.account_id);
|
|
||||||
send_update_lobby_data_bb(other_c);
|
|
||||||
} catch (const out_of_range&) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (send_updates_for_this_m) {
|
|
||||||
send_team_membership_change_notifications(c);
|
|
||||||
}
|
|
||||||
if (send_updates_for_other_m) {
|
|
||||||
try {
|
|
||||||
auto other_c = s->find_client(nullptr, cmd.guild_card_number);
|
|
||||||
send_team_membership_change_notifications(other_c);
|
|
||||||
} catch (const out_of_range&) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5454,7 +5428,7 @@ static void on_EA_BB(shared_ptr<Client> c, uint16_t command, uint32_t flag, stri
|
|||||||
s->team_index->buy_reward(team->team_id, reward.key, reward.team_points, reward.reward_flag);
|
s->team_index->buy_reward(team->team_id, reward.key, reward.team_points, reward.reward_flag);
|
||||||
|
|
||||||
if (reward.reward_flag != TeamIndex::Team::RewardFlag::NONE) {
|
if (reward.reward_flag != TeamIndex::Team::RewardFlag::NONE) {
|
||||||
send_team_metadata_change_notifications(s, team, TeamMetadataChange::REWARD_FLAGS);
|
send_team_metadata_change_notifications(s, team, 0, TeamMetadataChange::REWARD_FLAGS);
|
||||||
}
|
}
|
||||||
if (!reward.reward_item.empty()) {
|
if (!reward.reward_item.empty()) {
|
||||||
c->current_bank().add_item(reward.reward_item, *s->item_stack_limits(c->version()));
|
c->current_bank().add_item(reward.reward_item, *s->item_stack_limits(c->version()));
|
||||||
@@ -5477,7 +5451,7 @@ static void on_EA_BB(shared_ptr<Client> c, uint16_t command, uint32_t flag, stri
|
|||||||
} else {
|
} else {
|
||||||
s->team_index->rename(team->team_id, new_team_name);
|
s->team_index->rename(team->team_id, new_team_name);
|
||||||
send_command(c, 0x1FEA, 0x00000000);
|
send_command(c, 0x1FEA, 0x00000000);
|
||||||
send_team_metadata_change_notifications(s, team, TeamMetadataChange::TEAM_NAME);
|
send_team_metadata_change_notifications(s, team, 0, TeamMetadataChange::TEAM_NAME);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-20
@@ -4118,9 +4118,9 @@ void send_change_event(shared_ptr<ServerState> s, uint8_t new_event) {
|
|||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// BB teams
|
// BB teams
|
||||||
|
|
||||||
void send_team_membership_info(shared_ptr<Client> c) {
|
void send_update_team_membership(shared_ptr<Client> c) {
|
||||||
auto team = c->team();
|
auto team = c->team();
|
||||||
S_TeamMembershipInformation_BB_12EA cmd;
|
S_UpdateTeamMembership_BB_12EA cmd;
|
||||||
if (team) {
|
if (team) {
|
||||||
cmd.membership = team->base_membership_for_member(c->login->account->account_id);
|
cmd.membership = team->base_membership_for_member(c->login->account->account_id);
|
||||||
}
|
}
|
||||||
@@ -4131,14 +4131,10 @@ static S_TeamInfoForPlayer_BB_13EA_15EA_Entry team_metadata_for_client(shared_pt
|
|||||||
auto team = c->team();
|
auto team = c->team();
|
||||||
S_TeamInfoForPlayer_BB_13EA_15EA_Entry cmd;
|
S_TeamInfoForPlayer_BB_13EA_15EA_Entry cmd;
|
||||||
cmd.lobby_client_id = c->lobby_client_id;
|
cmd.lobby_client_id = c->lobby_client_id;
|
||||||
cmd.guild_card_number2 = c->login->account->account_id;
|
cmd.guild_card_number = c->login->account->account_id;
|
||||||
cmd.player_name = c->character()->disp.name;
|
cmd.player_name = c->character()->disp.name;
|
||||||
if (team) {
|
if (team) {
|
||||||
cmd.guild_card_number = c->login->account->account_id;
|
cmd.membership = team->base_membership_for_member(c->login->account->account_id);
|
||||||
cmd.team_id = team->team_id;
|
|
||||||
cmd.privilege_level = team->members.at(c->login->account->account_id).privilege_level();
|
|
||||||
cmd.team_member_count = min<size_t>(team->members.size(), 100);
|
|
||||||
cmd.team_name.encode(team->name);
|
|
||||||
if (team->flag_data) {
|
if (team->flag_data) {
|
||||||
cmd.flag_data = *team->flag_data;
|
cmd.flag_data = *team->flag_data;
|
||||||
}
|
}
|
||||||
@@ -4317,31 +4313,26 @@ void send_team_reward_list(shared_ptr<Client> c, bool show_purchased) {
|
|||||||
void send_team_metadata_change_notifications(
|
void send_team_metadata_change_notifications(
|
||||||
shared_ptr<ServerState> s,
|
shared_ptr<ServerState> s,
|
||||||
shared_ptr<const TeamIndex::Team> team,
|
shared_ptr<const TeamIndex::Team> team,
|
||||||
|
uint32_t changed_member_account_id,
|
||||||
uint8_t what) {
|
uint8_t what) {
|
||||||
using TMC = TeamMetadataChange;
|
using TMC = TeamMetadataChange;
|
||||||
for (const auto& it : team->members) {
|
for (const auto& it : team->members) {
|
||||||
try {
|
try {
|
||||||
auto member_c = s->find_client(nullptr, it.second.account_id);
|
auto member_c = s->find_client(nullptr, it.second.account_id);
|
||||||
if (what & TMC::TEAM_MASTER) {
|
bool is_changed_client = (member_c->login && (member_c->login->account->account_id == changed_member_account_id));
|
||||||
|
if (is_changed_client || (what & TMC::TEAM_MASTER)) {
|
||||||
send_update_lobby_data_bb(member_c);
|
send_update_lobby_data_bb(member_c);
|
||||||
}
|
}
|
||||||
if (what & (TMC::TEAM_MASTER | TMC::TEAM_NAME)) {
|
if (is_changed_client || (what & (TMC::TEAM_MASTER | TMC::TEAM_NAME | TMC::TEAM_MEMBER_COUNT))) {
|
||||||
send_team_membership_info(member_c);
|
send_update_team_membership(member_c);
|
||||||
}
|
}
|
||||||
if (what & (TMC::TEAM_MASTER | TMC::FLAG_DATA | TMC::TEAM_NAME)) {
|
if (is_changed_client || (what & (TMC::TEAM_MASTER | TMC::FLAG_DATA | TMC::TEAM_NAME | TMC::TEAM_MEMBER_COUNT))) {
|
||||||
send_update_team_metadata_for_client(member_c);
|
send_update_team_metadata_for_client(member_c);
|
||||||
}
|
}
|
||||||
if (what & TMC::REWARD_FLAGS) {
|
if (is_changed_client || (what & TMC::REWARD_FLAGS)) {
|
||||||
send_update_team_reward_flags(member_c);
|
send_update_team_reward_flags(member_c);
|
||||||
}
|
}
|
||||||
} catch (const out_of_range&) {
|
} catch (const out_of_range&) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_team_membership_change_notifications(shared_ptr<Client> changed_c) {
|
|
||||||
send_update_lobby_data_bb(changed_c);
|
|
||||||
send_update_team_metadata_for_client(changed_c);
|
|
||||||
send_team_membership_info(changed_c);
|
|
||||||
send_update_team_reward_flags(changed_c);
|
|
||||||
}
|
|
||||||
|
|||||||
+4
-3
@@ -447,7 +447,7 @@ void send_change_event(std::shared_ptr<Client> c, uint8_t new_event);
|
|||||||
void send_change_event(std::shared_ptr<Lobby> l, uint8_t new_event);
|
void send_change_event(std::shared_ptr<Lobby> l, uint8_t new_event);
|
||||||
void send_change_event(std::shared_ptr<ServerState> s, uint8_t new_event);
|
void send_change_event(std::shared_ptr<ServerState> s, uint8_t new_event);
|
||||||
|
|
||||||
void send_team_membership_info(std::shared_ptr<Client> c); // 12EA
|
void send_update_team_membership(std::shared_ptr<Client> c); // 12EA
|
||||||
void send_update_team_metadata_for_client(std::shared_ptr<Client> c); // 15EA (to all clients in lobby, with only c's data)
|
void send_update_team_metadata_for_client(std::shared_ptr<Client> c); // 15EA (to all clients in lobby, with only c's data)
|
||||||
void send_all_nearby_team_metadatas_to_client(std::shared_ptr<Client> c, bool is_13EA); // 13EA/15EA (to only c, with all lobby clients' data)
|
void send_all_nearby_team_metadatas_to_client(std::shared_ptr<Client> c, bool is_13EA); // 13EA/15EA (to only c, with all lobby clients' data)
|
||||||
void send_update_team_reward_flags(std::shared_ptr<Client> c); // 1DEA
|
void send_update_team_reward_flags(std::shared_ptr<Client> c); // 1DEA
|
||||||
@@ -461,11 +461,12 @@ enum TeamMetadataChange : uint8_t {
|
|||||||
FLAG_DATA = 0x02,
|
FLAG_DATA = 0x02,
|
||||||
REWARD_FLAGS = 0x04,
|
REWARD_FLAGS = 0x04,
|
||||||
TEAM_NAME = 0x08,
|
TEAM_NAME = 0x08,
|
||||||
|
TEAM_MEMBER_COUNT = 0x10,
|
||||||
|
TEAM_CREATED = 0xFF,
|
||||||
TEAM_DISBANDED = 0xFF,
|
TEAM_DISBANDED = 0xFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
void send_team_metadata_change_notifications(
|
void send_team_metadata_change_notifications(
|
||||||
std::shared_ptr<ServerState> s,
|
std::shared_ptr<ServerState> s,
|
||||||
std::shared_ptr<const TeamIndex::Team> team,
|
std::shared_ptr<const TeamIndex::Team> team,
|
||||||
|
uint32_t changed_member_account_id,
|
||||||
uint8_t what);
|
uint8_t what);
|
||||||
void send_team_membership_change_notifications(std::shared_ptr<Client> changed_c);
|
|
||||||
|
|||||||
Reference in New Issue
Block a user