refine PC save file format
This commit is contained in:
+6
-6
@@ -681,8 +681,8 @@ static void a_encrypt_decrypt_pc_save_fn(Arguments& args) {
|
||||
for (size_t z = 0; z < charfile->entries.size(); z++) {
|
||||
if (charfile->entries[z].present) {
|
||||
try {
|
||||
charfile->entries[z].character = decrypt_fixed_size_data_section_t<PSOPCCharacterFile::CharacterEntry::Character, false>(
|
||||
&charfile->entries[z].character, sizeof(charfile->entries[z].character), round1_seed, skip_checksum, override_round2_seed);
|
||||
charfile->entries[z].encrypted = decrypt_fixed_size_data_section_t<PSOPCCharacterFile::CharacterEntry::EncryptedSection, false>(
|
||||
&charfile->entries[z].encrypted, sizeof(charfile->entries[z].encrypted), round1_seed, skip_checksum, override_round2_seed);
|
||||
} catch (const exception& e) {
|
||||
fprintf(stderr, "warning: cannot decrypt character %zu: %s\n", z, e.what());
|
||||
}
|
||||
@@ -691,12 +691,12 @@ static void a_encrypt_decrypt_pc_save_fn(Arguments& args) {
|
||||
} else {
|
||||
for (size_t z = 0; z < charfile->entries.size(); z++) {
|
||||
if (charfile->entries[z].present) {
|
||||
string encrypted = encrypt_fixed_size_data_section_t<PSOPCCharacterFile::CharacterEntry::Character, false>(
|
||||
charfile->entries[z].character, round1_seed);
|
||||
if (encrypted.size() != sizeof(PSOPCCharacterFile::CharacterEntry::Character)) {
|
||||
string encrypted = encrypt_fixed_size_data_section_t<PSOPCCharacterFile::CharacterEntry::EncryptedSection, false>(
|
||||
charfile->entries[z].encrypted, round1_seed);
|
||||
if (encrypted.size() != sizeof(PSOPCCharacterFile::CharacterEntry::EncryptedSection)) {
|
||||
throw logic_error("incorrect encrypted result size");
|
||||
}
|
||||
charfile->entries[z].character = *reinterpret_cast<const PSOPCCharacterFile::CharacterEntry::Character*>(encrypted.data());
|
||||
charfile->entries[z].encrypted = *reinterpret_cast<const PSOPCCharacterFile::CharacterEntry::EncryptedSection*>(encrypted.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+31
-22
@@ -188,10 +188,12 @@ struct SaveFileChatShortcutEntryT {
|
||||
}
|
||||
} __packed__;
|
||||
using SaveFileShortcutEntryDC = SaveFileChatShortcutEntryT<false, TextEncoding::MARKED, 0x3C>;
|
||||
using SaveFileShortcutEntryPC = SaveFileChatShortcutEntryT<false, TextEncoding::UTF16, 0x3C>;
|
||||
using SaveFileShortcutEntryGC = SaveFileChatShortcutEntryT<true, TextEncoding::MARKED, 0x50>;
|
||||
using SaveFileShortcutEntryXB = SaveFileChatShortcutEntryT<false, TextEncoding::MARKED, 0x50>;
|
||||
using SaveFileShortcutEntryBB = SaveFileChatShortcutEntryT<false, TextEncoding::UTF16, 0x50>;
|
||||
check_struct_size(SaveFileShortcutEntryDC, 0x40);
|
||||
check_struct_size(SaveFileShortcutEntryPC, 0x7C);
|
||||
check_struct_size(SaveFileShortcutEntryGC, 0x54);
|
||||
check_struct_size(SaveFileShortcutEntryXB, 0x54);
|
||||
check_struct_size(SaveFileShortcutEntryBB, 0xA4);
|
||||
@@ -371,31 +373,38 @@ struct PSOPCCharacterFile { // PSO______SYS and PSO______SYD
|
||||
/* 00010 */ parray<uint8_t, 0x430> unknown_a1;
|
||||
struct CharacterEntry {
|
||||
/* 0000 */ le_uint32_t present = 1; // 1 if character present, 0 if empty
|
||||
struct Character {
|
||||
struct EncryptedSection {
|
||||
/* 0000 */ le_uint32_t checksum = 0;
|
||||
/* 0004 */ PlayerInventory inventory;
|
||||
/* 0350 */ PlayerDispDataDCPCV3 disp;
|
||||
/* 0420 */ be_uint32_t flags = 0;
|
||||
/* 0424 */ be_uint32_t creation_timestamp = 0;
|
||||
/* 0428 */ be_uint32_t signature = 0x6C5D889E;
|
||||
/* 042C */ be_uint32_t play_time_seconds = 0;
|
||||
/* 0430 */ be_uint32_t option_flags = 0x00040058;
|
||||
/* 0434 */ be_uint32_t save_count = 1;
|
||||
// TODO: Figure out what this is. On GC, this is where the bank data goes.
|
||||
/* 0438 */ parray<uint8_t, 0x7D4> unknown_a2;
|
||||
/* 0C0C */ GuildCardPC guild_card;
|
||||
/* 0CFC */ parray<SaveFileSymbolChatEntryPC, 12> symbol_chats;
|
||||
// TODO: Figure out what this is. On GC, this is where chat shortcuts and
|
||||
// challenge/battle records go.
|
||||
/* 123C */ parray<uint8_t, 0xAA0> unknown_a3;
|
||||
/* 1CDC */ parray<le_uint16_t, 20> tech_menu_shortcut_entries;
|
||||
/* 1D04 */ parray<uint8_t, 0x2C> unknown_a4;
|
||||
/* 1D30 */ pstring<TextEncoding::ASCII, 0x10> serial_number; // As %08X (not decimal)
|
||||
/* 1D40 */ pstring<TextEncoding::ASCII, 0x10> access_key; // As decimal
|
||||
struct Character {
|
||||
/* 0000 */ PlayerInventory inventory;
|
||||
/* 034C */ PlayerDispDataDCPCV3 disp;
|
||||
/* 041C */ be_uint32_t flags = 0;
|
||||
/* 0420 */ be_uint32_t creation_timestamp = 0;
|
||||
/* 0424 */ be_uint32_t signature = 0x6C5D889E;
|
||||
/* 0428 */ be_uint32_t play_time_seconds = 0;
|
||||
/* 042C */ be_uint32_t option_flags = 0x00040058;
|
||||
/* 0430 */ be_uint32_t save_count = 1;
|
||||
/* 0434 */ pstring<TextEncoding::ASCII, 0x1C> ppp_username;
|
||||
/* 0450 */ pstring<TextEncoding::ASCII, 0x10> ppp_password;
|
||||
/* 0460 */ QuestFlags quest_flags;
|
||||
/* 0660 */ PlayerBank60 bank;
|
||||
/* 0C08 */ GuildCardPC guild_card;
|
||||
/* 0CF8 */ parray<SaveFileSymbolChatEntryPC, 12> symbol_chats;
|
||||
/* 1238 */ parray<SaveFileShortcutEntryPC, 20> shortcuts;
|
||||
/* 1BE8 */ PlayerRecordsBattle battle_records;
|
||||
/* 1C00 */ PlayerRecordsChallengePC challenge_records;
|
||||
/* 1CD8 */ parray<le_uint16_t, 20> tech_menu_shortcut_entries;
|
||||
/* 1D00 */ parray<le_uint32_t, 10> choice_search_config;
|
||||
/* 1D28 */ parray<uint8_t, 4> unknown_a2;
|
||||
/* 1D2C */ pstring<TextEncoding::ASCII, 0x10> serial_number; // As %08X (not decimal)
|
||||
/* 1D3C */ pstring<TextEncoding::ASCII, 0x10> access_key; // As decimal
|
||||
/* 1D4C */
|
||||
} __packed_ws__(Character, 0x1D4C);
|
||||
/* 0004 */ Character character;
|
||||
/* 1D50 */ le_uint32_t round2_seed = 0;
|
||||
/* 1D54 */
|
||||
} __packed_ws__(Character, 0x1D54);
|
||||
/* 0004 */ Character character;
|
||||
} __packed_ws__(EncryptedSection, 0x1D54);
|
||||
/* 0004 */ EncryptedSection encrypted;
|
||||
/* 1D58 */ parray<uint8_t, 0x3C> unused;
|
||||
/* 1D94 */
|
||||
} __packed_ws__(CharacterEntry, 0x1D94);
|
||||
|
||||
Reference in New Issue
Block a user