implement rename team command
This commit is contained in:
+19
-18
@@ -3335,8 +3335,9 @@ struct C_SetTeamFlag_BB_0FEA {
|
|||||||
parray<le_uint16_t, 0x20 * 0x20> flag_data;
|
parray<le_uint16_t, 0x20 * 0x20> flag_data;
|
||||||
} __packed__;
|
} __packed__;
|
||||||
|
|
||||||
// 10EA: Delete team result
|
// 10EA: Delete team (C->S) and result (S->C)
|
||||||
// No arguments except header.flag
|
// No arguments (C->S)
|
||||||
|
// No arguments except header.flag (S->C)
|
||||||
|
|
||||||
// 11EA: Change team member privilege level
|
// 11EA: Change team member privilege level
|
||||||
// The format below is used only when the client sends this command; when the
|
// The format below is used only when the client sends this command; when the
|
||||||
@@ -3371,16 +3372,17 @@ struct S_TeamMembershipInformation_BB_12EA {
|
|||||||
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 of these to determine if the player is in a
|
||||||
// team or not - if they are all zero, the player is not in a team.
|
// team or not - if they are all zero, the player is not in a team.
|
||||||
le_uint32_t guild_card_number = 0;
|
/* 0000 */ le_uint32_t guild_card_number = 0;
|
||||||
le_uint32_t team_id = 0;
|
/* 0004 */ le_uint32_t team_id = 0;
|
||||||
le_uint32_t unknown_a3 = 0;
|
/* 0008 */ le_uint32_t unknown_a3 = 0;
|
||||||
le_uint32_t unknown_a4 = 0;
|
/* 000C */ le_uint32_t unknown_a4 = 0;
|
||||||
le_uint32_t privilege_level = 0;
|
/* 0010 */ le_uint32_t privilege_level = 0;
|
||||||
pstring<TextEncoding::UTF16, 0x10> team_name;
|
/* 0014 */ pstring<TextEncoding::UTF16, 0x10> team_name;
|
||||||
le_uint32_t guild_card_number2 = 0;
|
/* 0034 */ le_uint32_t guild_card_number2 = 0;
|
||||||
le_uint32_t lobby_client_id = 0;
|
/* 0038 */ le_uint32_t lobby_client_id = 0;
|
||||||
pstring<TextEncoding::UTF16, 0x10> player_name;
|
/* 003C */ pstring<TextEncoding::UTF16, 0x10> player_name;
|
||||||
parray<le_uint16_t, 0x20 * 0x20> flag_data;
|
/* 005C */ parray<le_uint16_t, 0x20 * 0x20> flag_data;
|
||||||
|
/* 085C */
|
||||||
} __packed__;
|
} __packed__;
|
||||||
|
|
||||||
// 14EA (C->S): Get team info for lobby players
|
// 14EA (C->S): Get team info for lobby players
|
||||||
@@ -3455,16 +3457,15 @@ struct S_CrossTeamRanking_BB_1CEA {
|
|||||||
// 1DEA (S->C): Update team rewards bitmask
|
// 1DEA (S->C): Update team rewards bitmask
|
||||||
// header.flag specifies the new rewards bitmask.
|
// header.flag specifies the new rewards bitmask.
|
||||||
|
|
||||||
// 1EEA (C->S): Unknown
|
// 1EEA (C->S): Rename team
|
||||||
// header.flag is used, but it's unknown what the value means.
|
// header.flag is used, but it's unknown what the value means.
|
||||||
|
|
||||||
struct C_Unknown_BB_1EEA {
|
struct C_RenameTeam_BB_1EEA {
|
||||||
pstring<TextEncoding::UTF16, 0x10> unknown_a1;
|
pstring<TextEncoding::UTF16, 0x10> new_team_name;
|
||||||
} __packed__;
|
} __packed__;
|
||||||
|
|
||||||
// 1FEA (S->C): Action result
|
// 1FEA (S->C): Rename team result
|
||||||
// This command behaves exactly like 02EA. This command is presumably the
|
// This command behaves like 02EA, but is sent in response to 1EEA instead.
|
||||||
// response to whatever 1EEA does.
|
|
||||||
|
|
||||||
// 20EA: Unknown
|
// 20EA: Unknown
|
||||||
// header.flag is used, but no other arguments. When sent by the server,
|
// header.flag is used, but no other arguments. When sent by the server,
|
||||||
|
|||||||
@@ -4888,6 +4888,29 @@ static void on_EA_BB(shared_ptr<Client> c, uint16_t command, uint32_t flag, stri
|
|||||||
case 0x1CEA:
|
case 0x1CEA:
|
||||||
send_cross_team_ranking(c);
|
send_cross_team_ranking(c);
|
||||||
break;
|
break;
|
||||||
|
case 0x1EEA: {
|
||||||
|
const auto& cmd = check_size_t<C_RenameTeam_BB_1EEA>(data);
|
||||||
|
auto team = c->team();
|
||||||
|
string new_team_name = cmd.new_team_name.decode(c->language());
|
||||||
|
if (!team) {
|
||||||
|
// TODO: What's the right error code to use here?
|
||||||
|
send_command(c, 0x1FEA, 0x00000001);
|
||||||
|
} else if (s->team_index->get_by_name(new_team_name)) {
|
||||||
|
send_command(c, 0x1FEA, 0x00000002);
|
||||||
|
} else {
|
||||||
|
s->team_index->rename(team->team_id, new_team_name);
|
||||||
|
send_command(c, 0x1FEA, 0x00000000);
|
||||||
|
for (const auto& it : team->members) {
|
||||||
|
try {
|
||||||
|
auto member_c = s->find_client(nullptr, it.second.serial_number);
|
||||||
|
send_update_team_metadata_for_client(c);
|
||||||
|
send_team_membership_info(c);
|
||||||
|
} catch (const out_of_range&) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw runtime_error("invalid team command");
|
throw runtime_error("invalid team command");
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-1
@@ -292,7 +292,7 @@ vector<shared_ptr<const TeamIndex::Team>> TeamIndex::all() const {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<const TeamIndex::Team> TeamIndex::create(string& name, uint32_t master_serial_number, const string& master_name) {
|
shared_ptr<const TeamIndex::Team> TeamIndex::create(const string& name, uint32_t master_serial_number, const string& master_name) {
|
||||||
auto team = make_shared<Team>(this->next_team_id++);
|
auto team = make_shared<Team>(this->next_team_id++);
|
||||||
save_file(this->directory + "/base.json", JSON::dict({{"NextTeamID", this->next_team_id}}).serialize());
|
save_file(this->directory + "/base.json", JSON::dict({{"NextTeamID", this->next_team_id}}).serialize());
|
||||||
|
|
||||||
@@ -316,6 +316,16 @@ void TeamIndex::disband(uint32_t team_id) {
|
|||||||
team->delete_files();
|
team->delete_files();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TeamIndex::rename(uint32_t team_id, const std::string& new_team_name) {
|
||||||
|
auto team = this->id_to_team.at(team_id);
|
||||||
|
if (!this->name_to_team.emplace(new_team_name, team).second) {
|
||||||
|
throw runtime_error("team name is already in use");
|
||||||
|
}
|
||||||
|
this->name_to_team.erase(team->name);
|
||||||
|
team->name = new_team_name;
|
||||||
|
team->save_config();
|
||||||
|
}
|
||||||
|
|
||||||
void TeamIndex::add_member(uint32_t team_id, uint32_t serial_number, const string& name) {
|
void TeamIndex::add_member(uint32_t team_id, uint32_t serial_number, const string& name) {
|
||||||
auto team = this->id_to_team.at(team_id);
|
auto team = this->id_to_team.at(team_id);
|
||||||
if (!this->serial_number_to_team.emplace(serial_number, team).second) {
|
if (!this->serial_number_to_team.emplace(serial_number, team).second) {
|
||||||
|
|||||||
+2
-1
@@ -127,8 +127,9 @@ public:
|
|||||||
std::shared_ptr<const Team> get_by_serial_number(uint32_t serial_number) const;
|
std::shared_ptr<const Team> get_by_serial_number(uint32_t serial_number) const;
|
||||||
std::vector<std::shared_ptr<const Team>> all() const;
|
std::vector<std::shared_ptr<const Team>> all() const;
|
||||||
|
|
||||||
std::shared_ptr<const Team> create(std::string& name, uint32_t master_serial_number, const std::string& master_name);
|
std::shared_ptr<const Team> create(const std::string& name, uint32_t master_serial_number, const std::string& master_name);
|
||||||
void disband(uint32_t team_id);
|
void disband(uint32_t team_id);
|
||||||
|
void rename(uint32_t team_id, const std::string& new_name);
|
||||||
|
|
||||||
void add_member(uint32_t team_id, uint32_t serial_number, const std::string& name);
|
void add_member(uint32_t team_id, uint32_t serial_number, const std::string& name);
|
||||||
void remove_member(uint32_t serial_number);
|
void remove_member(uint32_t serial_number);
|
||||||
|
|||||||
Reference in New Issue
Block a user