implement some bb guild card commands
This commit is contained in:
@@ -194,6 +194,11 @@ static void server_command_dbgid(shared_ptr<ServerState>, shared_ptr<Lobby>,
|
||||
c->prefer_high_lobby_client_id = !c->prefer_high_lobby_client_id;
|
||||
}
|
||||
|
||||
static void server_command_get_self_card(shared_ptr<ServerState>, shared_ptr<Lobby>,
|
||||
shared_ptr<Client> c, const std::u16string&) {
|
||||
send_guild_card(c, c);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Lobby commands
|
||||
|
||||
@@ -844,6 +849,7 @@ static const unordered_map<u16string, ChatCommandDefinition> chat_commands({
|
||||
{u"$dbgid" , {server_command_dbgid , nullptr , u"Usage:\ndbgid"}},
|
||||
{u"$edit" , {server_command_edit , nullptr , u"Usage:\nedit <stat> <value>"}},
|
||||
{u"$event" , {server_command_lobby_event , proxy_command_lobby_event , u"Usage:\nevent <name>"}},
|
||||
{u"$gc" , {server_command_get_self_card , nullptr , u"Usage:\ngc"}},
|
||||
{u"$infhp" , {server_command_infinite_hp , proxy_command_infinite_hp , u"Usage:\ninfhp"}},
|
||||
{u"$inftp" , {server_command_infinite_tp , proxy_command_infinite_tp , u"Usage:\ninftp"}},
|
||||
{u"$item" , {server_command_item , nullptr , u"Usage:\nitem <item-code>"}},
|
||||
|
||||
+13
-18
@@ -1405,7 +1405,7 @@ struct S_QuestMenuEntry {
|
||||
le_uint32_t menu_id;
|
||||
le_uint32_t item_id;
|
||||
ptext<CharT, 0x20> name;
|
||||
ptext<CharT, ShortDescLength> short_desc;
|
||||
ptext<CharT, ShortDescLength> short_description;
|
||||
};
|
||||
struct S_QuestMenuEntry_PC_A2_A4 : S_QuestMenuEntry<char16_t, 0x70> { };
|
||||
struct S_QuestMenuEntry_GC_A2_A4 : S_QuestMenuEntry<char, 0x70> { };
|
||||
@@ -2261,14 +2261,14 @@ struct S_Unknown_GC_Ep3_E8 {
|
||||
|
||||
// This struct is for documentation purposes only; newserv ignores the contents
|
||||
// of this command.
|
||||
struct C_ClientChecksum_01E8 {
|
||||
struct C_GuildCardChecksum_01E8 {
|
||||
le_uint32_t checksum;
|
||||
le_uint32_t unused;
|
||||
};
|
||||
|
||||
// 02E8 (S->C): Accept guild card file checksum
|
||||
// 02E8 (S->C): Accept/decline guild card file checksum
|
||||
|
||||
struct S_AcceptClientChecksum_BB_02E8 {
|
||||
struct S_GuildCardChecksumResponse_BB_02E8 {
|
||||
le_uint32_t verify;
|
||||
le_uint32_t unused;
|
||||
};
|
||||
@@ -2278,11 +2278,7 @@ struct S_AcceptClientChecksum_BB_02E8 {
|
||||
// Server should send the guild card file data using DC commands.
|
||||
|
||||
// 04E8 (C->S): Add guild card
|
||||
|
||||
struct C_AddOrUpdateGuildCard_BB_04E8_06E8_07E8 {
|
||||
// TODO: Document this format
|
||||
parray<uint8_t, 0x0108> unknown_a1;
|
||||
};
|
||||
// Format is GuildCardBB (see Player.hh)
|
||||
|
||||
// 05E8 (C->S): Delete guild card
|
||||
|
||||
@@ -2291,10 +2287,10 @@ struct C_DeleteGuildCard_BB_05E8_08E8 {
|
||||
};
|
||||
|
||||
// 06E8 (C->S): Set guild card text
|
||||
// Same format as 04E8.
|
||||
// Format is GuildCardBB (see Player.hh)
|
||||
|
||||
// 07E8 (C->S): Add blocked user
|
||||
// Same format as 04E8.
|
||||
// Format is GuildCardBB (see Player.hh)
|
||||
|
||||
// 08E8 (C->S): Delete blocked user
|
||||
// Same format as 05E8.
|
||||
@@ -2302,16 +2298,15 @@ struct C_DeleteGuildCard_BB_05E8_08E8 {
|
||||
// 09E8 (C->S): Write comment
|
||||
|
||||
struct C_WriteGuildCardComment_BB_09E8 {
|
||||
ptext<char16_t, 0x5A> comment;
|
||||
le_uint32_t guild_card_number;
|
||||
ptext<char16_t, 0x58> comment;
|
||||
};
|
||||
|
||||
// 0AE8 (C->S): Set guild card position in list
|
||||
|
||||
struct C_MoveGuildCard_BB_0AE8 {
|
||||
// TODO: One of these is the GC number, the other is the position. Figure out
|
||||
// which is which.
|
||||
le_uint32_t unknown_a1;
|
||||
le_uint32_t unknown_a2;
|
||||
le_uint32_t guild_card_number;
|
||||
le_uint32_t position;
|
||||
};
|
||||
|
||||
// E9 (S->C): Other player left spectator team (probably) (Episode 3)
|
||||
@@ -2597,7 +2592,7 @@ struct G_SendGuildCard_PC_V3 {
|
||||
le_uint32_t player_tag;
|
||||
le_uint32_t guild_card_number;
|
||||
ptext<CharT, 0x18> name;
|
||||
ptext<CharT, 0x48> desc;
|
||||
ptext<CharT, 0x48> description;
|
||||
parray<uint8_t, 0x24> unused2;
|
||||
uint8_t reserved1;
|
||||
uint8_t reserved2;
|
||||
@@ -2614,7 +2609,7 @@ struct G_SendGuildCard_BB_6x06 {
|
||||
le_uint32_t guild_card_number;
|
||||
ptext<char16_t, 0x18> name;
|
||||
ptext<char16_t, 0x10> team_name;
|
||||
ptext<char16_t, 0x58> desc;
|
||||
ptext<char16_t, 0x58> description;
|
||||
uint8_t reserved1;
|
||||
uint8_t reserved2;
|
||||
uint8_t section_id;
|
||||
|
||||
+18
-2
@@ -276,12 +276,28 @@ GuildCardV3::GuildCardV3() noexcept
|
||||
char_class(0) { }
|
||||
|
||||
GuildCardBB::GuildCardBB() noexcept
|
||||
: serial_number(0),
|
||||
: guild_card_number(0),
|
||||
reserved1(1),
|
||||
reserved2(1),
|
||||
section_id(0),
|
||||
char_class(0) { }
|
||||
|
||||
void GuildCardBB::clear() {
|
||||
this->guild_card_number = 0;
|
||||
this->name.clear();
|
||||
this->team_name.clear();
|
||||
this->description.clear();
|
||||
this->reserved1 = 1;
|
||||
this->reserved2 = 1;
|
||||
this->section_id = 0;
|
||||
this->char_class = 0;
|
||||
}
|
||||
|
||||
void GuildCardEntryBB::clear() {
|
||||
this->data.clear();
|
||||
this->unknown_a1.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PlayerBank::load(const string& filename) {
|
||||
@@ -506,7 +522,7 @@ PlayerBB ClientGameData::export_player_bb() {
|
||||
ret.serial_number = this->serial_number;
|
||||
ret.name = player->disp.name;
|
||||
ret.team_name = account->team_name;
|
||||
ret.guild_card_desc = player->guild_card_desc;
|
||||
ret.guild_card_description = player->guild_card_description;
|
||||
ret.reserved1 = 0;
|
||||
ret.reserved2 = 0;
|
||||
ret.section_id = player->disp.section_id;
|
||||
|
||||
+42
-34
@@ -213,7 +213,7 @@ struct GuildCardV3 {
|
||||
le_uint32_t player_tag;
|
||||
le_uint32_t serial_number;
|
||||
ptext<char, 0x18> name;
|
||||
ptext<char, 0x6C> desc;
|
||||
ptext<char, 0x6C> description;
|
||||
uint8_t reserved1; // should be 1
|
||||
uint8_t reserved2; // should be 1
|
||||
uint8_t section_id;
|
||||
@@ -224,29 +224,37 @@ struct GuildCardV3 {
|
||||
|
||||
// BB guild card format
|
||||
struct GuildCardBB {
|
||||
le_uint32_t serial_number;
|
||||
le_uint32_t guild_card_number;
|
||||
ptext<char16_t, 0x18> name;
|
||||
ptext<char16_t, 0x10> teamname;
|
||||
ptext<char16_t, 0x58> desc;
|
||||
ptext<char16_t, 0x10> team_name;
|
||||
ptext<char16_t, 0x58> description;
|
||||
uint8_t reserved1; // should be 1
|
||||
uint8_t reserved2; // should be 1
|
||||
uint8_t section_id;
|
||||
uint8_t char_class;
|
||||
|
||||
GuildCardBB() noexcept;
|
||||
void clear();
|
||||
} __attribute__((packed));
|
||||
|
||||
// an entry in the BB guild card file
|
||||
struct GuildCardEntryBB {
|
||||
GuildCardBB data;
|
||||
parray<uint8_t, 0xB4> unknown;
|
||||
// TODO: Almost all of this space (0x58 char16_ts) is probably the comment,
|
||||
// but is the unknown 4 bytes at the beginning or end of this space?
|
||||
parray<uint8_t, 0xB4> unknown_a1;
|
||||
|
||||
void clear();
|
||||
} __attribute__((packed));
|
||||
|
||||
// the format of the BB guild card file
|
||||
struct GuildCardFileBB {
|
||||
parray<uint8_t, 0x1F84> unknown_a1;
|
||||
GuildCardEntryBB entry[0x0068]; // that's 104 of them in decimal
|
||||
parray<uint8_t, 0x01AC> unknown_a2;
|
||||
parray<uint8_t, 6> unknown_a1;
|
||||
uint8_t num_guild_cards; // TODO: This is a guess. Verify this.
|
||||
uint8_t unknown_a2;
|
||||
parray<uint8_t, 0x1F7C> unknown_a3;
|
||||
GuildCardEntryBB entries[0x0068]; // that's 104 of them in decimal
|
||||
parray<uint8_t, 0x01AC> unknown_a4;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct KeyAndTeamConfigBB {
|
||||
@@ -404,31 +412,31 @@ struct PSOPlayerDataBB { // For command 61
|
||||
} __attribute__((packed));
|
||||
|
||||
struct PlayerBB { // Used in 00E7 command
|
||||
PlayerInventory inventory; // player
|
||||
PlayerDispDataBB disp; // player
|
||||
parray<uint8_t, 0x0010> unknown; // not saved
|
||||
le_uint32_t option_flags; // account
|
||||
parray<uint8_t, 0x0208> quest_data1; // player
|
||||
PlayerBank bank; // player
|
||||
le_uint32_t serial_number; // player
|
||||
ptext<char16_t, 0x18> name; // player
|
||||
ptext<char16_t, 0x10> team_name; // player
|
||||
ptext<char16_t, 0x58> guild_card_desc; // player
|
||||
uint8_t reserved1; // player
|
||||
uint8_t reserved2; // player
|
||||
uint8_t section_id; // player
|
||||
uint8_t char_class; // player
|
||||
le_uint32_t unknown3; // not saved
|
||||
parray<uint8_t, 0x04E0> symbol_chats; // account
|
||||
parray<uint8_t, 0x0A40> shortcuts; // account
|
||||
ptext<char16_t, 0x00AC> auto_reply; // player
|
||||
ptext<char16_t, 0x00AC> info_board; // player
|
||||
parray<uint8_t, 0x001C> unknown5; // not saved
|
||||
parray<uint8_t, 0x0140> challenge_data; // player
|
||||
parray<uint8_t, 0x0028> tech_menu_config; // player
|
||||
parray<uint8_t, 0x002C> unknown6; // not saved
|
||||
parray<uint8_t, 0x0058> quest_data2; // player
|
||||
KeyAndTeamConfigBB key_config; // account
|
||||
PlayerInventory inventory; // player
|
||||
PlayerDispDataBB disp; // player
|
||||
parray<uint8_t, 0x0010> unknown; // not saved
|
||||
le_uint32_t option_flags; // account
|
||||
parray<uint8_t, 0x0208> quest_data1; // player
|
||||
PlayerBank bank; // player
|
||||
le_uint32_t serial_number; // player
|
||||
ptext<char16_t, 0x18> name; // player
|
||||
ptext<char16_t, 0x10> team_name; // player
|
||||
ptext<char16_t, 0x58> guild_card_description; // player
|
||||
uint8_t reserved1; // player
|
||||
uint8_t reserved2; // player
|
||||
uint8_t section_id; // player
|
||||
uint8_t char_class; // player
|
||||
le_uint32_t unknown3; // not saved
|
||||
parray<uint8_t, 0x04E0> symbol_chats; // account
|
||||
parray<uint8_t, 0x0A40> shortcuts; // account
|
||||
ptext<char16_t, 0x00AC> auto_reply; // player
|
||||
ptext<char16_t, 0x00AC> info_board; // player
|
||||
parray<uint8_t, 0x001C> unknown5; // not saved
|
||||
parray<uint8_t, 0x0140> challenge_data; // player
|
||||
parray<uint8_t, 0x0028> tech_menu_config; // player
|
||||
parray<uint8_t, 0x002C> unknown6; // not saved
|
||||
parray<uint8_t, 0x0058> quest_data2; // player
|
||||
KeyAndTeamConfigBB key_config; // account
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
@@ -440,7 +448,7 @@ struct SavedPlayerDataBB { // .nsc file format
|
||||
PlayerBank bank;
|
||||
parray<uint8_t, 0x0140> challenge_data;
|
||||
PlayerDispDataBB disp;
|
||||
ptext<char16_t, 0x0058> guild_card_desc;
|
||||
ptext<char16_t, 0x0058> guild_card_description;
|
||||
ptext<char16_t, 0x00AC> info_board;
|
||||
PlayerInventory inventory;
|
||||
parray<uint8_t, 0x0208> quest_data1;
|
||||
|
||||
+114
-8
@@ -1571,14 +1571,120 @@ void process_player_preview_request_bb(shared_ptr<ServerState>, shared_ptr<Clien
|
||||
|
||||
void process_client_checksum_bb(shared_ptr<ServerState>, shared_ptr<Client> c,
|
||||
uint16_t command, uint32_t, const string& data) {
|
||||
if (command == 0x01E8) {
|
||||
check_size_v(data.size(), 8);
|
||||
send_accept_client_checksum_bb(c);
|
||||
} else if (command == 0x03E8) {
|
||||
check_size_v(data.size(), 0);
|
||||
send_guild_card_header_bb(c);
|
||||
} else {
|
||||
throw invalid_argument("unimplemented command");
|
||||
switch (command) {
|
||||
case 0x01E8: { // Check guild card file checksum
|
||||
check_size_v(data.size(), sizeof(C_GuildCardChecksum_01E8));
|
||||
// TODO: Presumably this response tells the client whether the file needs
|
||||
// to be downloaded at all. In the future, we could actually use the
|
||||
// checksum to skip downloading if the file isn't modified, to save time.
|
||||
S_GuildCardChecksumResponse_BB_02E8 cmd = {1, 0};
|
||||
send_command_t(c, 0x02E8, 0x00000000, cmd);
|
||||
break;
|
||||
}
|
||||
case 0x03E8: // Download guild card file
|
||||
check_size_v(data.size(), 0);
|
||||
send_guild_card_header_bb(c);
|
||||
break;
|
||||
case 0x04E8: { // Add guild card
|
||||
auto& new_gc = check_size_t<GuildCardBB>(data);
|
||||
auto& gcf = c->game_data.account()->guild_cards;
|
||||
if (gcf.num_guild_cards < sizeof(gcf.entries) / sizeof(gcf.entries[0])) {
|
||||
gcf.entries[gcf.num_guild_cards].data = new_gc;
|
||||
gcf.entries[gcf.num_guild_cards].unknown_a1.clear();
|
||||
c->log.info("Added guild card %" PRIu32 " at position %hhu",
|
||||
new_gc.guild_card_number.load(), gcf.num_guild_cards);
|
||||
gcf.num_guild_cards++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x05E8: { // Delete guild card
|
||||
auto& cmd = check_size_t<C_DeleteGuildCard_BB_05E8_08E8>(data);
|
||||
auto& gcf = c->game_data.account()->guild_cards;
|
||||
size_t z;
|
||||
for (z = 0; z < gcf.num_guild_cards; z++) {
|
||||
if (gcf.entries[z].data.guild_card_number == cmd.guild_card_number) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (z < gcf.num_guild_cards) {
|
||||
c->log.info("Deleted guild card %" PRIu32 " at position %zu",
|
||||
cmd.guild_card_number.load(), z);
|
||||
gcf.num_guild_cards--;
|
||||
for (z = 0; z < gcf.num_guild_cards; z++) {
|
||||
gcf.entries[z] = gcf.entries[z + 1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x06E8: { // Update guild card
|
||||
auto& new_gc = check_size_t<GuildCardBB>(data);
|
||||
auto& gcf = c->game_data.account()->guild_cards;
|
||||
for (size_t z = 0; z < gcf.num_guild_cards; z++) {
|
||||
if (gcf.entries[z].data.guild_card_number == new_gc.guild_card_number) {
|
||||
gcf.entries[z].data = new_gc;
|
||||
c->log.info("Updated guild card %" PRIu32 " at position %zu",
|
||||
new_gc.guild_card_number.load(), z);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x07E8: { // Add blocked user
|
||||
// TODO: Where do these go in GuildCardFileBB?
|
||||
// auto& cmd = check_size_t<C_DeleteGuildCard_BB_05E8_08E8>(data);
|
||||
throw runtime_error("blocked users are not yet implemented on BB");
|
||||
break;
|
||||
}
|
||||
case 0x08E8: { // Delete blocked user
|
||||
// TODO: Where do these go in GuildCardFileBB?
|
||||
// auto& cmd = check_size_t<C_DeleteGuildCard_BB_05E8_08E8>(data);
|
||||
throw runtime_error("blocked users are not yet implemented on BB");
|
||||
break;
|
||||
}
|
||||
case 0x09E8: { // Write comment
|
||||
// TODO: We need to know the comment storage format in the guild card file
|
||||
// in order to implement this (see comment in Player.hh). The
|
||||
// implementation should go very much like this:
|
||||
// auto& cmd = check_size_t<C_WriteGuildCardComment_BB_09E8>(data);
|
||||
// auto& gcf = c->game_data.account()->guild_cards;
|
||||
// for (size_t z = 0; z < gcf.num_guild_cards; z++) {
|
||||
// if (gcf.entries[z].data.guild_card_number == cmd.guild_card_number) {
|
||||
// gcf.entries[z].comment = cmd.comment;
|
||||
// c->log.info("Updated comment on guild card %" PRIu32 " at position %zu",
|
||||
// cmd.guild_card_number.load(), z);
|
||||
// }
|
||||
// }
|
||||
throw runtime_error("guild card comments are not yet implemented on BB");
|
||||
break;
|
||||
}
|
||||
case 0x0AE8: { // Move guild card in list
|
||||
auto& cmd = check_size_t<C_MoveGuildCard_BB_0AE8>(data);
|
||||
auto& gcf = c->game_data.account()->guild_cards;
|
||||
if (cmd.position >= gcf.num_guild_cards) {
|
||||
throw invalid_argument("invalid new position");
|
||||
}
|
||||
size_t index;
|
||||
for (index = 0; index < gcf.num_guild_cards; index++) {
|
||||
if (gcf.entries[index].data.guild_card_number == cmd.guild_card_number) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index >= gcf.num_guild_cards) {
|
||||
throw invalid_argument("player does not have requested guild card");
|
||||
}
|
||||
auto moved_gc = gcf.entries[index];
|
||||
for (; index < cmd.position; index++) {
|
||||
gcf.entries[index] = gcf.entries[index + 1];
|
||||
}
|
||||
for (; index > cmd.position; index--) {
|
||||
gcf.entries[index] = gcf.entries[index - 1];
|
||||
}
|
||||
gcf.entries[index] = moved_gc;
|
||||
c->log.info("Moved guild card %" PRIu32 " to position %zu",
|
||||
cmd.guild_card_number.load(), index);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw invalid_argument("invalid command");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -116,13 +116,15 @@ static void process_subcommand_send_guild_card(shared_ptr<ServerState>,
|
||||
|
||||
if (c->version == GameVersion::PC) {
|
||||
const auto* cmd = check_size_sc<G_SendGuildCard_PC_6x06>(data);
|
||||
c->game_data.player()->guild_card_desc = cmd->desc;
|
||||
c->game_data.player()->guild_card_description = cmd->description;
|
||||
} else if ((c->version == GameVersion::GC) || (c->version == GameVersion::XB)) {
|
||||
const auto* cmd = check_size_sc<G_SendGuildCard_V3_6x06>(data);
|
||||
c->game_data.player()->guild_card_desc = cmd->desc;
|
||||
c->game_data.player()->guild_card_description = cmd->description;
|
||||
} else if (c->version == GameVersion::BB) {
|
||||
const auto* cmd = check_size_sc<G_SendGuildCard_BB_6x06>(data);
|
||||
c->game_data.player()->guild_card_desc = cmd->desc;
|
||||
// Nothing to do... the command is blank; the server generates the guild
|
||||
// card to be sent
|
||||
} else {
|
||||
throw runtime_error("unsupported game version");
|
||||
}
|
||||
|
||||
send_guild_card(l->clients[flag], c);
|
||||
|
||||
+9
-14
@@ -321,11 +321,6 @@ void send_player_preview_bb(shared_ptr<Client> c, uint8_t player_index,
|
||||
}
|
||||
}
|
||||
|
||||
void send_accept_client_checksum_bb(shared_ptr<Client> c) {
|
||||
S_AcceptClientChecksum_BB_02E8 cmd = {1, 0};
|
||||
send_command_t(c, 0x02E8, 0x00000000, cmd);
|
||||
}
|
||||
|
||||
void send_guild_card_header_bb(shared_ptr<Client> c) {
|
||||
uint32_t checksum = crc32(
|
||||
&c->game_data.account()->guild_cards, sizeof(GuildCardFileBB));
|
||||
@@ -684,7 +679,7 @@ void send_card_search_result(
|
||||
|
||||
|
||||
template <typename CmdT>
|
||||
void send_guild_card_pc_v3(shared_ptr<Client> c, shared_ptr<Client> source) {
|
||||
void send_guild_card_pc_v3_t(shared_ptr<Client> c, shared_ptr<Client> source) {
|
||||
CmdT cmd;
|
||||
cmd.subcommand = 0x06;
|
||||
cmd.size = sizeof(CmdT) / 4;
|
||||
@@ -693,7 +688,7 @@ void send_guild_card_pc_v3(shared_ptr<Client> c, shared_ptr<Client> source) {
|
||||
cmd.guild_card_number = source->license->serial_number;
|
||||
cmd.name = source->game_data.player()->disp.name;
|
||||
remove_language_marker_inplace(cmd.name);
|
||||
cmd.desc = source->game_data.player()->guild_card_desc;
|
||||
cmd.description = source->game_data.player()->guild_card_description;
|
||||
cmd.reserved1 = 1;
|
||||
cmd.reserved2 = 1;
|
||||
cmd.section_id = source->game_data.player()->disp.section_id;
|
||||
@@ -709,7 +704,7 @@ void send_guild_card_bb(shared_ptr<Client> c, shared_ptr<Client> source) {
|
||||
cmd.guild_card_number = source->license->serial_number;
|
||||
cmd.name = remove_language_marker(source->game_data.player()->disp.name);
|
||||
cmd.team_name = remove_language_marker(source->game_data.account()->team_name);
|
||||
cmd.desc = source->game_data.player()->guild_card_desc;
|
||||
cmd.description = source->game_data.player()->guild_card_description;
|
||||
cmd.reserved1 = 1;
|
||||
cmd.reserved2 = 1;
|
||||
cmd.section_id = source->game_data.player()->disp.section_id;
|
||||
@@ -719,10 +714,10 @@ void send_guild_card_bb(shared_ptr<Client> c, shared_ptr<Client> source) {
|
||||
|
||||
void send_guild_card(shared_ptr<Client> c, shared_ptr<Client> source) {
|
||||
if (c->version == GameVersion::PC) {
|
||||
send_guild_card_pc_v3<G_SendGuildCard_PC_6x06>(c, source);
|
||||
send_guild_card_pc_v3_t<G_SendGuildCard_PC_6x06>(c, source);
|
||||
} else if ((c->version == GameVersion::GC) ||
|
||||
(c->version == GameVersion::XB)) {
|
||||
send_guild_card_pc_v3<G_SendGuildCard_V3_6x06>(c, source);
|
||||
send_guild_card_pc_v3_t<G_SendGuildCard_V3_6x06>(c, source);
|
||||
} else if (c->version == GameVersion::BB) {
|
||||
send_guild_card_bb(c, source);
|
||||
} else {
|
||||
@@ -850,8 +845,8 @@ void send_quest_menu_t(
|
||||
e.menu_id = menu_id;
|
||||
e.item_id = quest->menu_item_id;
|
||||
e.name = quest->name;
|
||||
e.short_desc = quest->short_description;
|
||||
add_color_inplace(e.short_desc);
|
||||
e.short_description = quest->short_description;
|
||||
add_color_inplace(e.short_description);
|
||||
}
|
||||
send_command_vt(c, is_download_menu ? 0xA4 : 0xA2, entries.size(), entries);
|
||||
}
|
||||
@@ -868,8 +863,8 @@ void send_quest_menu_t(
|
||||
e.menu_id = menu_id;
|
||||
e.item_id = item.item_id;
|
||||
e.name = item.name;
|
||||
e.short_desc = item.description;
|
||||
add_color_inplace(e.short_desc);
|
||||
e.short_description = item.description;
|
||||
add_color_inplace(e.short_description);
|
||||
}
|
||||
send_command_vt(c, is_download_menu ? 0xA4 : 0xA2, entries.size(), entries);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user