rewrite $bbchar implementation
This commit is contained in:
+1
-3
@@ -1029,14 +1029,12 @@ static void server_command_convert_char_to_bb(shared_ptr<Client> c, const std::s
|
||||
}
|
||||
|
||||
try {
|
||||
s->license_index->verify_bb(tokens[0].c_str(), tokens[1].c_str());
|
||||
c->pending_bb_save_license = s->license_index->verify_bb(tokens[0].c_str(), tokens[1].c_str());
|
||||
} catch (const exception& e) {
|
||||
send_text_message_printf(c, "$C6Login failed: %s", e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
c->pending_bb_save_username = tokens[0];
|
||||
|
||||
// Request the player data. The client will respond with a 61, and the handler
|
||||
// for that command will execute the conversion
|
||||
send_get_player_info(c);
|
||||
|
||||
+1
-1
@@ -201,7 +201,7 @@ struct Client : public std::enable_shared_from_this<Client> {
|
||||
uint32_t next_exp_value; // next EXP value to give
|
||||
G_SwitchStateChanged_6x05 last_switch_enabled_command;
|
||||
bool can_chat;
|
||||
std::string pending_bb_save_username;
|
||||
std::shared_ptr<License> pending_bb_save_license;
|
||||
uint8_t pending_bb_save_character_index;
|
||||
std::deque<std::function<void(uint32_t, uint32_t)>> function_call_response_queue;
|
||||
|
||||
|
||||
+11
-1
@@ -302,6 +302,16 @@ string ClientGameData::system_filename() const {
|
||||
return string_printf("system/players/system_%s.psosys", this->bb_username.c_str());
|
||||
}
|
||||
|
||||
string ClientGameData::character_filename(const std::string& bb_username, int8_t index) {
|
||||
if (bb_username.empty()) {
|
||||
throw logic_error("non-BB players do not have character data");
|
||||
}
|
||||
if (index < 0) {
|
||||
throw logic_error("character index is not set");
|
||||
}
|
||||
return string_printf("system/players/player_%s_%hhd.psochar", bb_username.c_str(), index);
|
||||
}
|
||||
|
||||
string ClientGameData::character_filename(int8_t index) const {
|
||||
if (this->bb_username.empty()) {
|
||||
throw logic_error("non-BB players do not have character data");
|
||||
@@ -312,7 +322,7 @@ string ClientGameData::character_filename(int8_t index) const {
|
||||
if (index < 0) {
|
||||
throw logic_error("character index is not set");
|
||||
}
|
||||
return string_printf("system/players/player_%s_%hhd.psochar", this->bb_username.c_str(), index);
|
||||
return this->character_filename(this->bb_username, index);
|
||||
}
|
||||
|
||||
string ClientGameData::guild_card_filename() const {
|
||||
|
||||
+9
-8
@@ -112,6 +112,15 @@ public:
|
||||
const PlayerDispDataBBPreview& preview,
|
||||
std::shared_ptr<const LevelTable> level_table);
|
||||
|
||||
std::string system_filename() const;
|
||||
static std::string character_filename(const std::string& bb_username, int8_t index);
|
||||
std::string character_filename(int8_t index = -1) const;
|
||||
std::string guild_card_filename() const;
|
||||
std::string shared_bank_filename() const;
|
||||
|
||||
std::string legacy_player_filename() const;
|
||||
std::string legacy_account_filename() const;
|
||||
|
||||
void save_all();
|
||||
void save_system_file() const;
|
||||
static void save_character_file(
|
||||
@@ -147,12 +156,4 @@ private:
|
||||
void save_and_clear_external_bank();
|
||||
|
||||
void load_all_files();
|
||||
|
||||
std::string system_filename() const;
|
||||
std::string character_filename(int8_t index = -1) const;
|
||||
std::string guild_card_filename() const;
|
||||
std::string shared_bank_filename() const;
|
||||
|
||||
std::string legacy_player_filename() const;
|
||||
std::string legacy_account_filename() const;
|
||||
};
|
||||
|
||||
@@ -194,13 +194,6 @@ PlayerDispDataBBPreview PlayerDispDataBB::to_preview() const {
|
||||
return pre;
|
||||
}
|
||||
|
||||
void PlayerDispDataBB::apply_preview(const PlayerDispDataBBPreview& pre) {
|
||||
this->stats.level = pre.level;
|
||||
this->stats.experience = pre.experience;
|
||||
this->visual = pre.visual;
|
||||
this->name = pre.name;
|
||||
}
|
||||
|
||||
void PlayerDispDataBB::apply_dressing_room(const PlayerDispDataBBPreview& pre) {
|
||||
this->visual.name_color = pre.visual.name_color;
|
||||
this->visual.extra_model = pre.visual.extra_model;
|
||||
|
||||
@@ -112,7 +112,7 @@ struct PlayerDispDataBB;
|
||||
struct PlayerVisualConfig {
|
||||
/* 00 */ pstring<TextEncoding::ASCII, 0x10> name;
|
||||
/* 10 */ parray<uint8_t, 8> unknown_a2;
|
||||
/* 18 */ le_uint32_t name_color = 0x00000000; // ARGB
|
||||
/* 18 */ le_uint32_t name_color = 0xFFFFFFFF; // ARGB
|
||||
/* 1C */ uint8_t extra_model = 0;
|
||||
/* 1D */ parray<uint8_t, 0x0F> unused;
|
||||
// See compute_name_color_checksum for details on how this is computed. This
|
||||
|
||||
+33
-33
@@ -2973,42 +2973,42 @@ static void on_61_98(shared_ptr<Client> c, uint16_t command, uint32_t flag, stri
|
||||
s->remove_client_from_lobby(c);
|
||||
|
||||
} else if (command == 0x61) {
|
||||
if (!c->pending_bb_save_username.empty()) {
|
||||
string prev_bb_username = c->game_data.get_bb_username();
|
||||
int8_t prev_bb_character_index = c->game_data.bb_character_index;
|
||||
if (c->pending_bb_save_license) {
|
||||
shared_ptr<License> dest_license = c->pending_bb_save_license;
|
||||
c->pending_bb_save_license.reset();
|
||||
|
||||
c->game_data.set_bb_username(c->pending_bb_save_username);
|
||||
c->game_data.bb_character_index = c->pending_bb_save_character_index;
|
||||
string filename = ClientGameData::character_filename(dest_license->bb_username, c->pending_bb_save_character_index);
|
||||
if (s->player_files_manager->get_character(filename)) {
|
||||
send_text_message(c, "$C6The target player\nis currently loaded.\nSign off in Blue\nBurst and try again.");
|
||||
|
||||
// Update a few fields for BB
|
||||
const auto& p = c->game_data.character();
|
||||
uint8_t prev_version = p->disp.visual.version;
|
||||
p->disp.visual.version = 4;
|
||||
uint32_t prev_name_color_checksum = p->disp.visual.name_color_checksum;
|
||||
p->disp.visual.name_color_checksum = 0x00000000;
|
||||
|
||||
bool failure = false;
|
||||
try {
|
||||
c->game_data.save_character_file();
|
||||
} catch (const exception& e) {
|
||||
send_text_message_printf(c, "$C6PSOBB player data could\nnot be saved:\n%s", e.what());
|
||||
failure = true;
|
||||
} else {
|
||||
auto bb_player = PSOBBCharacterFile::create_from_config(
|
||||
dest_license->serial_number,
|
||||
c->language(),
|
||||
player->disp.visual,
|
||||
player->disp.name.decode(c->language()),
|
||||
s->level_table);
|
||||
bb_player->disp.visual.version = 4;
|
||||
bb_player->disp.visual.name_color_checksum = 0x00000000;
|
||||
bb_player->inventory = player->inventory;
|
||||
bb_player->disp.stats.advance_to_level(bb_player->disp.visual.char_class, player->disp.stats.level, s->level_table);
|
||||
bb_player->disp.stats.experience = player->disp.stats.experience;
|
||||
bb_player->disp.technique_levels_v1 = player->disp.technique_levels_v1;
|
||||
bb_player->auto_reply = player->auto_reply;
|
||||
bb_player->info_board = player->info_board;
|
||||
bb_player->battle_records = player->battle_records;
|
||||
bb_player->challenge_records = player->challenge_records;
|
||||
bb_player->choice_search_config = player->choice_search_config;
|
||||
try {
|
||||
ClientGameData::save_character_file(filename, c->game_data.system(), bb_player);
|
||||
send_text_message_printf(c,
|
||||
"$C6BB player data saved\nas player %hhu for user\n%s",
|
||||
static_cast<uint8_t>(c->pending_bb_save_character_index + 1),
|
||||
dest_license->bb_username.c_str());
|
||||
} catch (const exception& e) {
|
||||
send_text_message_printf(c, "$C6PSOBB player data could\nnot be saved:\n%s", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
p->disp.visual.version = prev_version;
|
||||
p->disp.visual.name_color_checksum = prev_name_color_checksum;
|
||||
|
||||
if (!failure) {
|
||||
send_text_message_printf(c,
|
||||
"$C6BB player data saved\nas player %hhu for user\n%s",
|
||||
static_cast<uint8_t>(c->pending_bb_save_character_index + 1),
|
||||
c->pending_bb_save_username.c_str());
|
||||
}
|
||||
|
||||
c->game_data.set_bb_username(prev_bb_username);
|
||||
c->game_data.bb_character_index = prev_bb_character_index;
|
||||
|
||||
c->pending_bb_save_username.clear();
|
||||
}
|
||||
|
||||
// We use 61 during the lobby server init sequence to trigger joining an
|
||||
|
||||
+17
-6
@@ -208,10 +208,11 @@ PSOBBBaseSystemFile::PSOBBBaseSystemFile() {
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<PSOBBCharacterFile> PSOBBCharacterFile::create_from_preview(
|
||||
shared_ptr<PSOBBCharacterFile> PSOBBCharacterFile::create_from_config(
|
||||
uint32_t guild_card_number,
|
||||
uint8_t language,
|
||||
const PlayerDispDataBBPreview& preview,
|
||||
const PlayerVisualConfig& visual,
|
||||
const std::string& name,
|
||||
shared_ptr<const LevelTable> level_table) {
|
||||
static const array<array<PlayerInventoryItem, 5>, 12> initial_inventory{{
|
||||
{
|
||||
@@ -300,7 +301,7 @@ shared_ptr<PSOBBCharacterFile> PSOBBCharacterFile::create_from_preview(
|
||||
},
|
||||
}};
|
||||
|
||||
array<uint8_t, 0xE8> config_hunter_ranger{
|
||||
static const array<uint8_t, 0xE8> config_hunter_ranger{
|
||||
{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -316,7 +317,7 @@ shared_ptr<PSOBBCharacterFile> PSOBBCharacterFile::create_from_preview(
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
array<uint8_t, 0xE8> config_force{
|
||||
static const array<uint8_t, 0xE8> config_force{
|
||||
{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -334,8 +335,10 @@ shared_ptr<PSOBBCharacterFile> PSOBBCharacterFile::create_from_preview(
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
|
||||
|
||||
auto ret = make_shared<PSOBBCharacterFile>();
|
||||
ret->disp.visual = visual;
|
||||
ret->disp.name.encode(name, language);
|
||||
|
||||
const auto& initial_items = initial_inventory.at(preview.visual.char_class);
|
||||
const auto& initial_items = initial_inventory.at(visual.char_class);
|
||||
ret->inventory.num_items = initial_items.size();
|
||||
for (size_t z = 0; z < initial_items.size(); z++) {
|
||||
ret->inventory.items[z] = initial_items[z];
|
||||
@@ -347,7 +350,6 @@ shared_ptr<PSOBBCharacterFile> PSOBBCharacterFile::create_from_preview(
|
||||
ret->disp.config[z] = config[z];
|
||||
}
|
||||
|
||||
ret->disp.apply_preview(preview);
|
||||
ret->disp.stats.reset_to_base(ret->disp.visual.char_class, level_table);
|
||||
ret->disp.technique_levels_v1.clear(0xFF);
|
||||
if (ret->disp.visual.class_flags & 0x80) {
|
||||
@@ -369,6 +371,15 @@ shared_ptr<PSOBBCharacterFile> PSOBBCharacterFile::create_from_preview(
|
||||
return ret;
|
||||
}
|
||||
|
||||
shared_ptr<PSOBBCharacterFile> PSOBBCharacterFile::create_from_preview(
|
||||
uint32_t guild_card_number,
|
||||
uint8_t language,
|
||||
const PlayerDispDataBBPreview& preview,
|
||||
shared_ptr<const LevelTable> level_table) {
|
||||
return PSOBBCharacterFile::create_from_config(
|
||||
guild_card_number, language, preview.visual, preview.name.decode(language), level_table);
|
||||
}
|
||||
|
||||
PSOBBCharacterFile::SymbolChatEntry PSOBBCharacterFile::DefaultSymbolChatEntry::to_entry() const {
|
||||
SymbolChatEntry ret;
|
||||
ret.present = 1;
|
||||
|
||||
@@ -219,6 +219,12 @@ struct PSOBBCharacterFile {
|
||||
|
||||
PSOBBCharacterFile() = default;
|
||||
|
||||
static std::shared_ptr<PSOBBCharacterFile> create_from_config(
|
||||
uint32_t guild_card_number,
|
||||
uint8_t language,
|
||||
const PlayerVisualConfig& visual,
|
||||
const std::string& name,
|
||||
std::shared_ptr<const LevelTable> level_table);
|
||||
static std::shared_ptr<PSOBBCharacterFile> create_from_preview(
|
||||
uint32_t guild_card_number,
|
||||
uint8_t language,
|
||||
|
||||
Reference in New Issue
Block a user